209 lines
6.8 KiB
C#
209 lines
6.8 KiB
C#
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using asap.core;
|
|
using DG.Tweening;
|
|
using Game;
|
|
using UI.Wheel;
|
|
using UnityEngine;
|
|
|
|
namespace UI.HookWheel
|
|
{
|
|
public class HookWheelRewardComponent : AbstractWheelRewardComponent
|
|
{
|
|
private Tweener _tweener;
|
|
private int currentSegment;
|
|
private int lastSegment;
|
|
|
|
private float lastValue;
|
|
protected override string StartSound => "audio_ui_hookwheel_arrow_spin_start";
|
|
protected override string LoopedSound => "audio_ui_hookwheel_arrow_spin_loop";
|
|
protected override string EndSound => "audio_ui_hookwheel_arrow_spin_end";
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
fx_spin = gameObject.FindChildGameObject("fx_ui_hookwheel_spin")?.gameObject;
|
|
fx_arrow_spin = gameObject.FindChildGameObject("fx_ui_hookwheel_arrow_spin")?.gameObject;
|
|
lightAni = gameObject.FindChildGameObject("p_light")?.GetComponent<Animation>();
|
|
zhizhenTrans = gameObject.FindChildGameObject("zhizhen")?.GetComponent<Transform>();
|
|
|
|
for (var i = 1; i <= 3; i++)
|
|
{
|
|
var key = $"fx_ui_hookwheel_reward_claim_0{i}";
|
|
if (_fxNameObjs.ContainsKey(key)) continue;
|
|
var fx = gameObject.FindChildGameObject(key)?.gameObject;
|
|
if (fx == null) continue;
|
|
fx.SetActive(false);
|
|
_fxNameObjs.Add(key, fx);
|
|
}
|
|
}
|
|
|
|
protected override void Start()
|
|
{
|
|
base.Start();
|
|
lightAni.Play("light_idle");
|
|
}
|
|
|
|
protected override void InitUI()
|
|
{
|
|
base.InitUI();
|
|
fx_spin.SetActive(false);
|
|
fx_arrow_spin.SetActive(false);
|
|
wheelClipLoop = lightAni?["light_spin_loop"];
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
public RectTransform GetRewardFlySource(int index)
|
|
{
|
|
return (wheelRewardCells[index] as HookWheelRewardCell)?.RewardFlySource;
|
|
}
|
|
|
|
protected override void EffectStart()
|
|
{
|
|
base.EffectStart();
|
|
InitPointerAni();
|
|
_ = LightStarAni();
|
|
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);
|
|
SetClipLoopSpeed(currentVelocity);
|
|
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);
|
|
lightAni.Play("light_idle");
|
|
}
|
|
|
|
protected override async Task DelayShow()
|
|
{
|
|
await base.DelayShow();
|
|
fx_spin?.SetActive(true);
|
|
}
|
|
|
|
protected override void RevertTargetEndCallbcak()
|
|
{
|
|
base.RevertTargetEndCallbcak();
|
|
_ = LightEndAni();
|
|
}
|
|
|
|
#region ui
|
|
|
|
private GameObject fx_spin;
|
|
private GameObject fx_arrow_spin;
|
|
private Animation lightAni;
|
|
private AnimationState wheelClipLoop;
|
|
private Transform zhizhenTrans;
|
|
private readonly Dictionary<string, GameObject> _fxNameObjs = new();
|
|
|
|
#endregion ui
|
|
|
|
#region private
|
|
|
|
private void SetClipLoopSpeed(float currentVelocity)
|
|
{
|
|
wheelClipLoop.speed = Mathf.Max(Mathf.Abs(currentVelocity / 360), 0.1f);
|
|
}
|
|
|
|
private async Task LightStarAni()
|
|
{
|
|
var time = lightAni["light_spin_start"].length;
|
|
lightAni.Play("light_spin_start");
|
|
await Awaiters.Seconds(time);
|
|
|
|
lightAni.Play("light_spin_loop");
|
|
}
|
|
|
|
private async Task LightEndAni()
|
|
{
|
|
var remainingTime = wheelClipLoop.length * (1f - wheelClipLoop.normalizedTime);
|
|
await Awaiters.Seconds(remainingTime);
|
|
|
|
var clipEndTime = lightAni["light_spin_end"].length;
|
|
lightAni.Play("light_spin_end");
|
|
await Awaiters.Seconds(clipEndTime);
|
|
|
|
var clipRewardTime = lightAni["light_reward"].length;
|
|
lightAni.Play("light_reward");
|
|
}
|
|
|
|
#endregion private
|
|
|
|
#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
|
|
}
|
|
} |