152 lines
5.0 KiB
C#
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
|
|
}
|
|
} |