using System.Collections.Generic; using System.Threading.Tasks; using asap.core; using DG.Tweening; using Game; using UI.Wheel; using UnityEngine; namespace EventBossFight { public class EventBossFightWheelRewardComponent : AbstractWheelRewardComponent { private Tweener _tweener; private int currentSegment; private int lastSegment; private float lastValue; protected override string StartSound => "audio_eventbossfight_wheel_spin_start"; protected override string LoopedSound => "audio_eventbossfight_wheel_spin_loop"; protected override string EndSound => "audio_eventbossfight_wheel_spin_stop"; protected override void Awake() { base.Awake(); fx_spin = gameObject.FindChildGameObject("fx_ui_hookwheel_spin")?.gameObject; fx_arrow_spin = gameObject.FindChildGameObject("fx_eventbossfight_wheel_spin")?.gameObject; zhizhenTrans = gameObject.FindChildGameObject("zhizhen")?.GetComponent(); var key = "fx_eventbossfight_wheel_flash"; var fx = gameObject.FindChildGameObject(key)?.gameObject; if (fx != null) { fx.SetActive(false); _fxNameObjs.TryAdd(key, fx); } } protected override void InitUI() { base.InitUI(); fx_spin?.SetActive(false); fx_arrow_spin?.SetActive(false); } public override void SetData(List rewards) { for (var i = 0; i < rewards.Count && i < wheelRewardCells.Length; i++) wheelRewardCells[i].SetData(rewards[i]); } public override void ShowUI() { foreach (var rewardCell in wheelRewardCells) rewardCell.ShowUI(); } protected override void EffectStart() { base.EffectStart(); InitPointerAni(); foreach (var fx in _fxNameObjs) fx.Value?.SetActive(false); fx_arrow_spin.SetActive(true); } protected override void EffectUpdate(float currentVelocity, float currentValue) { base.EffectUpdate(currentVelocity, currentValue); PointerAni(currentValue, currentVelocity); } protected override async Task EffectEnd(IWheelReward reward) { fx_spin.SetActive(false); fx_arrow_spin.SetActive(false); if (_fxNameObjs.TryGetValue(reward.Fx, out var value)) value.SetActive(true); zhizhenTrans.rotation = Quaternion.Euler(0, 0, 0); if (!string.IsNullOrEmpty(reward.Audio)) GContext.Publish(new EventUISound(reward.Audio)); await base.EffectEnd(reward); } protected override async Task DelayShow() { await base.DelayShow(); fx_spin?.SetActive(true); } #region ui private GameObject fx_spin; private GameObject fx_arrow_spin; private Transform zhizhenTrans; private readonly Dictionary _fxNameObjs = new(); #endregion ui #region Pointer Animation private void InitPointerAni() { var currentValue = rewardContainer.eulerAngles.z; lastValue = currentValue; lastSegment = GetSegment(currentValue); } private void PointerAni(float currentValue, float currentVelocity) { currentSegment = GetSegment(currentValue); lastSegment = GetSegment(lastValue); var normalizeCurrentAngle = NormalizeAngle(currentValue); if (currentSegment != lastSegment) { var direction = GetCrossDirection(lastSegment, currentSegment); var time = wheelAngle / currentVelocity; var pointerTargetAngle = Mathf.Abs(Mathf.Clamp01(normalizeCurrentAngle / wheelAngle) * pointerAngle); zhizhenTrans.DORotate(new Vector3(0, 0, direction * pointerTargetAngle), time) .OnComplete(() => { _tweener?.Kill(); _tweener = zhizhenTrans.DORotate(Vector3.zero, revertAngleTime); }); } lastValue = currentValue; } private int GetSegment(float angle) { var normalizedAngle = NormalizeAngle(angle); return Mathf.FloorToInt(normalizedAngle / SegmentAngle); } private float NormalizeAngle(float angle) { angle %= FULL_CIRCLE; if (angle < 0) angle += FULL_CIRCLE; return angle; } private int GetCrossDirection(int fromSegment, int toSegment) { var diff = toSegment - fromSegment; if ((fromSegment == MaxSegment && toSegment == 0) || (fromSegment == 0 && toSegment == MaxSegment)) diff = -diff; return diff < 0 ? 1 : -1; } #endregion Pointer Animation } }