using System; using System.Linq; using System.Threading.Tasks; using asap.core; using DG.Tweening; using GameCore; using TMPro; using UniRx; using UnityEngine; using UnityEngine.UI; public class EventBreakTaskView : MonoBehaviour { [SerializeField] private RewardItemNew reward; [SerializeField] private Image barProgress; [SerializeField] private TMP_Text textProgress; [SerializeField] private Transform rewardFlyTarget; [SerializeField] private GameObject fxGem, fxBar; [SerializeField] private Animation aniTask; private int _targetItemId, _taskId; private float _taskChangeDuration, _barFlashDuration, _rewardFlyDuration, _rewardShowDuration; private GameObject _rewardFly; private ItemData _rewardItemData; private bool _isUpdatingTaskDisplay = false; private void Start() { EventBreakAct.EventAggregator.GetEvent().Subscribe(OnBlockBreak).AddTo(this); } public void Init(EventBreakTaskInfo info, float taskChangeDuration, float barFlashDuration, float rewardFlyDuration, GameObject rewardFly, float rewardShowDuration) { reward.SetData(info.Reward, abbr: true); barProgress.fillAmount = (float)info.CurrentGemProgress / info.TotalGemRequired; textProgress.text = $"{info.CurrentGemProgress}/{info.TotalGemRequired}"; _targetItemId = info.TargetItemId; // Debug.Log($"[EventBreak] target item id:{_targetItemId}", this); _taskId = info.TaskId; _taskChangeDuration = taskChangeDuration; _barFlashDuration = barFlashDuration; _rewardFly = rewardFly; _rewardItemData = info.Reward; _rewardFlyDuration = rewardFlyDuration; _rewardShowDuration = rewardShowDuration; } private async void OnBlockBreak(EventBreakBlockBreak e) { try { var drillModel = GContext.container.Resolve(); if (e.Item.id != _targetItemId) return; await MakeRewardFly(e); var info = drillModel.TaskInfoList.First(i => i.TargetItemId == _targetItemId); UpdateDisplay(info); } catch (Exception ex) { Debug.Log($"[EventBreak] BreakBlockError: {ex.Message}\n{ex.StackTrace}"); } } private async Task MakeRewardFly(EventBreakBlockBreak e) { try { var rewardFly = Instantiate(_rewardFly, transform.parent).GetComponent(); rewardFly.SetRewardPopupData(e.Item); rewardFly.transform.position = e.BreakPos; rewardFly.gameObject.SetActive(true); var t = rewardFly.transform.Find("fx_eventbreakdrill_reward_show"); if (t != null) t.gameObject.SetActive(true); t = rewardFly.transform.Find("fx_eventbreakdrill_reward_fly"); if (t != null) t.gameObject.SetActive(true); rewardFly.GetComponent().Play("reward_common_open"); await Task.Delay(TimeSpan.FromSeconds(_rewardShowDuration)); rewardFly.GetComponent().Play("reward_common_close"); await Task.Delay(24 * 1000 / 60); rewardFly.GetComponent().alpha = 1; rewardFly.text_num.gameObject.SetActive(false); rewardFly.transform.localScale = Vector3.one * 0.64f; await Awaiters.NextFrame; // _ = rewardFly.ParticleAttractor(); await Task.Delay(TimeSpan.FromSeconds(_rewardFlyDuration)); await rewardFly.transform.DOMove(rewardFlyTarget.position, _rewardFlyDuration).AsyncWaitForCompletion(); Destroy(rewardFly.gameObject); // UIManager.BlockInput(5f); } catch (Exception ex) { Debug.Log($"[EventBreak] BreakBlockError: {ex.Message}\n{ex.StackTrace}"); } } /// /// will never be running twice at the same time. /// /// current task info, the actual one public async void UpdateDisplay(EventBreakTaskInfo info) { if (_isUpdatingTaskDisplay) return; try { // UIManager.BlockInput(5f); _isUpdatingTaskDisplay = true; PlayGemFx(); var s = textProgress.text.Split("/"); var currentCount = int.Parse(s[0]); var totalCount = int.Parse(s[1]); if (_taskId != info.TaskId) { await DOTween.To(() => currentCount, v => currentCount = v, totalCount, _taskChangeDuration) .OnUpdate(() => { barProgress.fillAmount = (float)currentCount / totalCount; textProgress.text = $"{currentCount}/{totalCount}"; }) .AsyncWaitForCompletion(); await PlayProgressBarFx(); var panel = await UIManager.Instance.ShowUINotLoading(UITypes.EventBreakRewardPopupPanel); var t = new TaskCompletionSource(); panel.GetComponent().Init(_rewardItemData, EventBreakAct.Ctx.GetGemIdx(gemId: _targetItemId), () => t.SetResult(1)); await t.Task; EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.StrongUnblock)); await Awaiters.NextFrame; currentCount = 0; totalCount = info.TotalGemRequired; aniTask.Play("reward_refresh"); await Awaiters.NextFrame; reward.SetData(info.Reward, abbr: true); barProgress.fillAmount = 0f; textProgress.text = $"0/{info.TotalGemRequired}"; _taskId = info.TaskId; _rewardItemData = info.Reward; await Awaiters.NextFrame; } await DOTween.To(() => currentCount, v => currentCount = v, info.CurrentGemProgress, _taskChangeDuration) .OnUpdate(() => { barProgress.fillAmount = (float)currentCount / totalCount; textProgress.text = $"{currentCount}/{totalCount}"; }) .AsyncWaitForCompletion(); _isUpdatingTaskDisplay = false; EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Unblock)); } catch (Exception ex) { Debug.Log($"[EventBreak] TaskView: {ex.Message}\n{ex.StackTrace}", this); _isUpdatingTaskDisplay = false; } } private void PlayGemFx() { fxGem.SetActive(false); fxGem.SetActive(true); } private async Task PlayProgressBarFx() { fxBar.SetActive(false); fxBar.SetActive(true); await Task.Delay(TimeSpan.FromSeconds(_taskChangeDuration)); fxBar.SetActive(false); } } public class EventBreakBlockBreak { public Vector2 BreakPos { get; set; } public ItemData Item {get; set;} }