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 tcs = new TaskCompletionSource(); } public class ChallengeFailEvent { public int oldStep; public TaskCompletionSource tcs = new TaskCompletionSource(); } // 定义显示Tips // public class ChallengeLevelTipsEvent { public bool IsGm; public int oldScore; public int newScore; public TaskCompletionSource 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 _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(); GetComponent().worldCamera = Camera.main; _levelTipController = transform.Find("EventChallengeLevelTips").GetComponent(); // _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().Subscribe(ShowPlayer).AddTo(_disposables); GContext.OnEvent().Subscribe(PlayAni).AddTo(_disposables); GContext.OnEvent().Subscribe(OnFail).AddTo(_disposables); GContext.OnEvent().Subscribe(OnShowLevelTips).AddTo(_disposables); } private void Start() { var listItemData = GContext.container.Resolve().GetItemDataByDropId(_fishingChallengeManager.eventChallengeMain.WinnerReward); var totalCount = listItemData.Sum(itemData => itemData.count); _textNumCash.GetComponent().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().TbRobot.DataMap; var uiService = GContext.container.Resolve(); 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(); 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(); _myHead.transform.localScale = Vector3.one; _myHead.transform.localPosition = Vector3.zero; _myHead.bg_head_myself.SetActive(true); uiService.SetHeadImage(_myHead.icon_head, GContext.container.Resolve().AvatarUrl); count = _headList.Count; } ////打乱headList顺序 // void Shuffle(int curCount) // { // var newHeadList = new List(); // var robotAccountList = new List(); // 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 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($"ChallengeMatchSceneUI => {message} "); } }