Files
2026-05-26 16:15:54 +08:00

556 lines
21 KiB
C#

using asap.core;
using GameCore;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UniRx;
using UnityEngine.UI;
using game;
using System.Threading.Tasks;
using DG.Tweening;
using Game;
using TMPro;
using UnityEngine.Serialization;
public class ChallengeShowPlayerEvent
{
public int oldStep;
}
public class ChallengePlayAniEvent
{
public int oldStep;
public int newStep;
public TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
}
public class ChallengeFailEvent
{
public int oldStep;
public TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
}
// 定义显示Tips
//
public class ChallengeLevelTipsEvent
{
public bool IsGm;
public int oldScore;
public int newScore;
public TaskCompletionSource<bool> tcs = new();
}
public class ShowResidueNumEvent
{
public int num;
}
// 比赛场景中显示头像奖励等的UI,挂载与比赛场景上
public class ChallengeMatchSceneUI : MonoBehaviour
{
//
private Transform icon_reward;
private Transform text_title;
private Transform _textNumCash;
// 地点
public ChallengeMatchSceneUIRegion[] uiRegion;
public GameObject[] tipPlaceHolder;
public GameObject eventChallengeHead;
private EventChallengeLevelTips _levelTipController;
private FishingChallengeManager _fishingChallengeManager;
private List<EventChallengeHead> _headList = new();
private EventChallengeHead _myHead;
private int count;
private CompositeDisposable _disposables = new();
// 本人起跳间隔
[Header("本人起跳到其他人开始起跳")]
public float jumpIntervalMy = 0.1f;
//起跳间隔
[Header("其他人起跳开始间隔")]
public float jumpInterval = 0.1f;
// 最后一个起跳到淘汰时间
[Header("最后一人起跳到开始落水")]
public float jumpToEliminateTime = 0.6f;
// 落水到平台下沉时间
// [Header("开始落水到沉船")]
// public float eliminateToPlatformTime = 0.5f;
//int maxCount = 3;
[Header("每个人落水间隔")] public float eliminateInterval = 0.01f;
[Header("跳水动画时长")] public float jumpDuration = 0.6f;
[Header("淘汰落水时长")] public float jumpDead = 0.2f;
[Header("箱子破坏前延时")] public float BreakDuration = 0.1f;
private void Awake()
{
_fishingChallengeManager = GContext.container.Resolve<FishingChallengeManager>();
GetComponent<Canvas>().worldCamera = Camera.main;
_levelTipController = transform.Find("EventChallengeLevelTips").GetComponent<EventChallengeLevelTips>();
// _levelTipController.SetSpeed(speed);
// _levelTipController.UpdateControllerTime(uptime1, wait2, wait3);
// var evt = new ChallengeSetAnimationEvent()
// {
// speed = speed,
// timeForUnlocking = _timeForUnlocking,
// timeForUnLockingEnd = _timeForUnlockingEnd,
// timeForAttacking_1 = _timeForAttacking_1,
// timeForAttacking_2 = _timeForAttacking_2,
// timeForAttackStart = _timeForAttackStart,
// timeForAttackEnd = _timeForAttackEnd,
// timeForAttackEndWait = _timeForAttackEndEnd,
// };
// GContext.Publish(evt);
icon_reward = transform.Find("taizi_reward/icon_reward/icon_reward");
text_title = transform.Find("taizi_reward/total_reward/text_title");
_textNumCash = transform.Find("taizi_reward/total_reward/text_num_cash");
GContext.OnEvent<ChallengeShowPlayerEvent>().Subscribe(ShowPlayer).AddTo(_disposables);
GContext.OnEvent<ChallengePlayAniEvent>().Subscribe(PlayAni).AddTo(_disposables);
GContext.OnEvent<ChallengeFailEvent>().Subscribe(OnFail).AddTo(_disposables);
GContext.OnEvent<ChallengeLevelTipsEvent>().Subscribe(OnShowLevelTips).AddTo(_disposables);
}
private void Start()
{
var listItemData = GContext.container.Resolve<PlayerItemData>().GetItemDataByDropId(_fishingChallengeManager.eventChallengeMain.WinnerReward);
var totalCount = listItemData.Sum(itemData => itemData.count);
_textNumCash.GetComponent<TMP_Text>().text = "x" + ConvertTools.GetNumberString(totalCount);
InitLevelTip(_fishingChallengeManager.fishingChallengeData.ProcessedScore);
}
public void InitLevelTip(int score )
{
var step = _fishingChallengeManager.GetStepByScore(score,true);
if (step > tipPlaceHolder.Length - 1)
{
return;
}
_levelTipController.transform.localPosition = tipPlaceHolder[step].transform.localPosition;
_levelTipController.gameObject.SetActive(true);
_levelTipController.Init(score);
}
private void ShowPlayer(ChallengeShowPlayerEvent challengeShowPlayerEvent)
{
var oldStep = challengeShowPlayerEvent.oldStep;
var robots = GContext.container.Resolve<cfg.Tables>().TbRobot.DataMap;
var uiService = GContext.container.Resolve<IUIService>();
var randomPos = uiRegion[oldStep];
var posTran = randomPos.posTran;
var myself = randomPos.myself;
if (_headList.Count > 0)
{
_headList.ForEach(x => Destroy(x.gameObject));
_headList.Clear();
Destroy(_myHead.gameObject);
}
var residual = posTran.Count;
for (int i = 0; i < residual; i++)
{
GameObject go = Instantiate(eventChallengeHead.gameObject, posTran[i]);
go.transform.localScale = Vector3.one;
go.transform.localPosition = Vector3.zero;
var head = go.GetComponent<EventChallengeHead>();
if (robots.TryGetValue(_fishingChallengeManager.fishingChallengeData.robotAccountList[i], out cfg.Robot robot))
{
uiService.SetHeadImage(head.icon_head, robot.Avatar);
}
_headList.Add(head);
}
_myHead = Instantiate(eventChallengeHead.gameObject, myself).GetComponent<EventChallengeHead>();
_myHead.transform.localScale = Vector3.one;
_myHead.transform.localPosition = Vector3.zero;
_myHead.bg_head_myself.SetActive(true);
uiService.SetHeadImage(_myHead.icon_head, GContext.container.Resolve<IUserService>().AvatarUrl);
count = _headList.Count;
}
////打乱headList顺序
// void Shuffle(int curCount)
// {
// var newHeadList = new List<EventChallengeHead>();
// var robotAccountList = new List<int>();
// int index = 0;
// for (int i = 0; i < curCount; i++)
// {
// newHeadList.Insert(index, _headList[i]);
// robotAccountList.Insert(index, _fishingChallengeManager.fishingChallengeData.robotAccountList[i]);
// index = UnityEngine.Random.Range(0, newHeadList.Count + 1);
// }
// _headList = newHeadList;
// _fishingChallengeManager.fishingChallengeData.robotAccountList = robotAccountList;
// }
#if UNITY_EDITOR
bool isShow;
string oldStepStr, newStepStr;
private string _scoreStr; // 添加到渔获的价值
private int _level;
string oldScoreStr, newScoreStr;
private void Update()
{
if (Input.GetKeyDown(KeyCode.K))
{
isShow = !isShow;
}
if (Input.GetKeyDown(KeyCode.M))
{
_level = (_level + 1) % 7;
// _tipController.transform.localPosition = tipPlaceHolder[_level].transform.localPosition;
LocationLevelTips(_level);
}
}
private async void OnGUI()
{
GUILayout.Label($"当前段位: {_fishingChallengeManager.eventChallengeMain.ID}");
if (!isShow)
{
return;
}
// Set the button width and height
float buttonWidth = 300; // Replace with your desired width
float buttonHeight = 70; // Replace with your desired height
int fontSize = 40; // Replace with your desired font size
// Set the font size for text fields, buttons, and labels
GUI.skin.textField.fontSize = fontSize;
GUI.skin.button.fontSize = fontSize;
GUI.skin.label.fontSize = fontSize;
// 触发ChallengeShowPlayAniEvent 事件并能输入oldStep和newStep
GUILayout.Label("oldStep:");
oldStepStr = GUILayout.TextField(oldStepStr, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
int.TryParse(oldStepStr, out int oldStep);
if (GUILayout.Button("Fail"))
{
GContext.Publish(new ChallengeMatchPlayGMEvent() { step = oldStep });
ShowPlayer(new ChallengeShowPlayerEvent { oldStep = oldStep });
await Awaiters.Seconds(0.5f);
ChallengeFailEvent challengeFailEvent = new ChallengeFailEvent();
challengeFailEvent.oldStep = oldStep;
OnFail(challengeFailEvent);
}
GUILayout.Label("newStep:");
newStepStr = GUILayout.TextField(newStepStr, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
int.TryParse(newStepStr, out int newStep);
if (GUILayout.Button("PlayAni", GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)))
{
GContext.Publish(new ChallengeMatchPlayGMEvent() { step = oldStep });
ShowPlayer(new ChallengeShowPlayerEvent { oldStep = oldStep });
await Awaiters.Seconds(0.5f);
var challengePlayAniEvent = new ChallengePlayAniEvent();
challengePlayAniEvent.oldStep = oldStep;
challengePlayAniEvent.newStep = newStep;
PlayAni(challengePlayAniEvent);
}
GUILayout.Label("QualityScore:");
_scoreStr = GUILayout.TextField(_scoreStr,GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
int.TryParse(_scoreStr, out var score);
_fishingChallengeManager.SetQualityScore(score);
GUILayout.Label("oldScore:");
oldScoreStr = GUILayout.TextField(oldScoreStr, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
int.TryParse(oldScoreStr, out var oldScore);
//
GUILayout.Label("newScore:");
newScoreStr = GUILayout.TextField(newScoreStr, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
int.TryParse(newScoreStr, out var newScore);
//
if (GUILayout.Button("RunNewPlay", GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)))
{
// GContext.Publish(new ChallengeMatchPlayGMEvent() { step = oldStep });
var nStep = _fishingChallengeManager.GetStepByScore(oldScore,true);
var evt = new ChallengeInitStepEvent()
{
step = nStep
};
GContext.Publish(evt);
await Awaiters.NextFrame;
ShowPlayer(new ChallengeShowPlayerEvent { oldStep = nStep });
await Awaiters.Seconds(0.5f);
// 全部重置
var tipsEvent = new ChallengeLevelTipsEvent()
{
IsGm = true,
oldScore = oldScore,
newScore = newScore,
};
//OnShowLevelTips(tipsEvent);
GContext.Publish(tipsEvent);
}
}
#endif
private async void PlayAni(ChallengePlayAniEvent challengePlayAniEvent)
{
var oldStep = challengePlayAniEvent.oldStep;
var newStep = challengePlayAniEvent.newStep;
ChallengeMatchSceneUIRegion randomPos;
List<Transform> posTran;
Transform myself;
/// 更新剩余人数
ShowResidueNumEvent showResidueNumEvent = new ShowResidueNumEvent();
var eliminateNumber = _fishingChallengeManager.fishingChallengeData.eliminateNumber;
var newEliminate = _fishingChallengeManager.CalcResidualNumber(oldStep);
showResidueNumEvent.num = newEliminate;
GContext.Publish(showResidueNumEvent);
//
float speed = 1;
if (newStep > oldStep + 1)
{
speed = 0.7f;
}
//var uiRegionNum = uiRegion.Length;
//从oldStep到newStep
var brokeStepEvent = new ChallengeBrokeStepEvent
{
step = oldStep,
dealyTime = BreakDuration,
};
for (int i = oldStep; i < newStep; i++)
{
var regionIdx = Math.Min(uiRegion.Length - 1, i + 1);
randomPos = uiRegion[regionIdx];
posTran = randomPos.posTran;
myself = randomPos.myself;
int residual = posTran.Count;
// for (int j = 0; j < residual; j++)
// {
// _headList[j].rectTransform.SetParent(posTran[j]);
// }
// for (int j = residual; j < count; j++)
// {
// _headList[j].rectTransform.SetParent(posTran[residual - 1]);
// }
_myHead.rectTransform.SetParent(myself);
_myHead.rectTransform.localScale = Vector3.one;
_myHead.rectTransform.DOLocalMove(Vector3.zero,jumpDuration);
_myHead.headAni.Play("fx_anim_eventchallengehead_jump_success_01");
// 头狼起调
var myJumpAudioName = uiRegion[i].myJumpAudioName;
if (!string.IsNullOrEmpty(myJumpAudioName))
{
GContext.Publish(new EventUISound(myJumpAudioName));
}
await Awaiters.Seconds(jumpIntervalMy * speed);
// 跟随起跳
var followerJumpAudioName = uiRegion[i].followerJumpAudioName;
if (!string.IsNullOrEmpty(myJumpAudioName))
{
GContext.Publish(new EventUISound(followerJumpAudioName));
}
for (int j = 0; j < residual; j++)
{
await Awaiters.Seconds(jumpInterval * speed);
_headList[j].rectTransform.SetParent(posTran[j]);
_headList[j].rectTransform.DOLocalMove(Vector3.zero, jumpDuration).SetEase(Ease.OutCubic);
_headList[j].rectTransform.DOScale(Vector3.one, jumpDuration).SetEase(Ease.OutCubic);
_headList[j].headAni.Play("fx_anim_eventchallengehead_jump_success_01");
}
var posTranRect = uiRegion[i].posTranRect;
//淘汰动画
await Awaiters.Seconds(jumpToEliminateTime * speed);
// 播放动画声音
var audioName = uiRegion[i].fallAudioName;
if (!string.IsNullOrEmpty(audioName)){
GContext.Publish(new EventUISound(audioName));
}
//
int tranCount = posTranRect.Count;
RectTransform rectPos = posTranRect[0];
float width = 0, height = 0;
if (residual >= count)
{
GContext.Publish(brokeStepEvent);
}
else
{
for (int j = residual; j < count; j++)
{
if (tranCount > j - residual)
{
rectPos = posTranRect[j - residual];
width = rectPos.rect.width / 2;
height = rectPos.rect.height / 2;
}
Vector3 vector3 = new Vector3(UnityEngine.Random.Range(-width, width),
UnityEngine.Random.Range(-height, height), 0);
await Awaiters.Seconds(eliminateInterval * speed);
_headList[j].rectTransform.SetParent(rectPos);
_headList[j].rectTransform.DOScale(Vector3.one, jumpDead).SetEase(Ease.Linear);
_headList[j].rectTransform.DOLocalMove(vector3, jumpDead).SetEase(Ease.Linear);
_headList[j].headAni.Play("fx_anim_eventchallengehead_jump_defeat_01");
if (j == residual)
{
// 播放破坏动画
GContext.Publish(brokeStepEvent);
}
}
}
//从i到i+1平台,起点0不动
if (i > 0)
{
// await Awaiters.Seconds(eliminateToPlatformTime * speed );
GContext.Publish(new ChallengeMatchPlayEvent() { step = i });
}
count = residual;
newEliminate -= eliminateNumber[i];
showResidueNumEvent.num = newEliminate;
GContext.Publish(showResidueNumEvent);
// if (i < eliminateNumber.Count - 2)
// {
// _fishingChallengeManager.AddStageReward(i);
// }
// 直接写添加奖品
// var itemDataList = playerItemData.GetItemDataByDropId(eventChallengeMain.StageReward[newStep], fishingChallengeData.mapId);
// playerItemData.AddItem(itemDataList);
await Awaiters.Seconds(1f * speed);
await brokeStepEvent.Tcs.Task; //
}
challengePlayAniEvent.tcs.SetResult(true);
}
private async void OnFail(ChallengeFailEvent challengeFailEvent)
{
int oldStep = challengeFailEvent.oldStep;
var rectPos = uiRegion[oldStep].myselfRect;
//淘汰动画
float width = rectPos.rect.width / 2;
float height = rectPos.rect.height / 2;
Vector3 vector3 = new Vector3(UnityEngine.Random.Range(-width, width), UnityEngine.Random.Range(-height, height), 0);
_myHead.rectTransform.SetParent(rectPos);
_myHead.rectTransform.localScale = Vector3.one;
_myHead.rectTransform.DOLocalMove(vector3, 0.2f).SetEase(Ease.Linear);
_myHead.headAni.Play("fx_anim_eventchallengehead_jump_defeat_01");
await Awaiters.Seconds(1f);
challengeFailEvent.tcs.SetResult(true);
}
// 注意多组的情况,根据分数算,可能要跳好多次
private async void OnShowLevelTips(ChallengeLevelTipsEvent tipsEvent)
{
Log("OnShowLevelTips");
var oldScore = tipsEvent.oldScore;
var newScore = tipsEvent.newScore;
var isGm = tipsEvent.IsGm;
if (oldScore == newScore)
{
InitLevelTip(oldScore);
tipsEvent.tcs.SetResult(true);
return;
}
var step = _fishingChallengeManager.GetStepByScore(oldScore,true);
var maxScore = _fishingChallengeManager.GetMaxScoreByStep(step);
if (_levelTipController && step >= 0 && step < tipPlaceHolder.Length )
{
LocationLevelTips(step);
var curScore = await _levelTipController.ShowTips(oldScore,newScore);
// 播放显示动画
if (maxScore == curScore)
{
await _levelTipController.PlayInVisibleAni();
await ReceiveStageReward(step);
await JumpStage(step, curScore, newScore,isGm);
}
}
tipsEvent.tcs.SetResult(true);
}
private void LocationLevelTips(int step)
{
_levelTipController.transform.localPosition = tipPlaceHolder[step].transform.localPosition;
_levelTipController.SetCurStep(step);
_levelTipController.gameObject.SetActive(true);
}
// 看看需要加什么动画类的东西么
public async Task ReceiveStageReward(int step)
{
Log($"ReceiveStageReward {step}");
_fishingChallengeManager.AddStageReward(step);
}
private static async Task JumpStage(int step, int curScore, int newScore,bool isGm)
{
Log("JumpStage");
// 清理下一个台子
var cleanEvent = new ChallengeCleanStageEvent
{
stage = step + 1,
};
GContext.Publish(cleanEvent);
await cleanEvent.Tcs.Task;
// 播放跳跃动画
var cspe = new ChallengePlayAniEvent() { oldStep = step, newStep = step + 1 };
GContext.Publish(cspe);
await cspe.tcs.Task;
// // 播放破坏动画
// var brokeStepEvent = new ChallengeBrokeStepEvent { step = step };
// GContext.Publish(brokeStepEvent);
// await brokeStepEvent.Tcs.Task;
// -- 进入下一个循环
// if (curScore != newScore || newScore == maxScore)
// {
var nextStageEvent = new ChallengeLevelTipsEvent
{
oldScore = curScore,
newScore = newScore,
IsGm = isGm,
};
GContext.Publish(nextStageEvent);
await nextStageEvent.tcs.Task;
// }
}
void OnDisable()
{
_disposables?.Dispose();
_disposables = null;
}
private static void Log(object message)
{
Debug.Log($"<color=orange>ChallengeMatchSceneUI => {message} </color>");
}
}