Files
ft/Client/Assets/Scripts/EventBossFight/Panel/EventBossFightWheelRewardComponent.cs
2026-06-29 21:18:33 +08:00

152 lines
5.0 KiB
C#

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<Transform>();
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<IWheelReward> 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<string, GameObject> _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
}
}