mainmenu completed
This commit is contained in:
8
Assets/Darkmatter/Code/Features/MainMenu/Buttons.meta
Normal file
8
Assets/Darkmatter/Code/Features/MainMenu/Buttons.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69d4557372f902f448f5acb3b8e3cbeb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
126
Assets/Darkmatter/Code/Features/MainMenu/Buttons/ButtonEffect.cs
Normal file
126
Assets/Darkmatter/Code/Features/MainMenu/Buttons/ButtonEffect.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using PrimeTween;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Darkmatter.Features.Mainmenu.Buttons
|
||||
{
|
||||
public enum ButtonEffectType
|
||||
{
|
||||
None,
|
||||
Scale,
|
||||
PunchScale,
|
||||
ShakePosition,
|
||||
ShakeRotation,
|
||||
Bounce,
|
||||
Pulse,
|
||||
Wobble,
|
||||
Flip,
|
||||
Spin
|
||||
}
|
||||
|
||||
[RequireComponent(typeof(Button))]
|
||||
[DisallowMultipleComponent]
|
||||
public class ButtonEffect : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private ButtonEffectType effect = ButtonEffectType.Scale;
|
||||
[SerializeField] private RectTransform target;
|
||||
|
||||
[Header("Shared")]
|
||||
[SerializeField, Min(0.01f)] private float duration = 0.3f;
|
||||
[SerializeField] private Ease ease = Ease.OutBack;
|
||||
[SerializeField, Min(0f)] private float loopInterval = 0.5f;
|
||||
|
||||
[Header("Effect Tuning")]
|
||||
[SerializeField] private float scaleAmount = 1.15f;
|
||||
[SerializeField] private float shakeStrength = 10f;
|
||||
[SerializeField] private float rotationStrength = 15f;
|
||||
|
||||
private Vector3 baseScale;
|
||||
private Vector3 baseEuler;
|
||||
private Vector3 baseLocalPosition;
|
||||
private Tween currentTween;
|
||||
private CancellationTokenSource loopCts;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (target == null) target = transform as RectTransform;
|
||||
baseScale = target.localScale;
|
||||
baseEuler = target.localEulerAngles;
|
||||
baseLocalPosition = target.localPosition;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
loopCts = CancellationTokenSource.CreateLinkedTokenSource(this.GetCancellationTokenOnDestroy());
|
||||
PlayLoopAsync(loopCts.Token).Forget();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
loopCts?.Cancel();
|
||||
loopCts?.Dispose();
|
||||
loopCts = null;
|
||||
currentTween.Stop();
|
||||
}
|
||||
|
||||
private async UniTaskVoid PlayLoopAsync(CancellationToken token)
|
||||
{
|
||||
while (!token.IsCancellationRequested)
|
||||
{
|
||||
Play();
|
||||
if (currentTween.isAlive)
|
||||
{
|
||||
await UniTask.WaitWhile(() => currentTween.isAlive, cancellationToken: token);
|
||||
}
|
||||
if (loopInterval > 0f)
|
||||
{
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(loopInterval), cancellationToken: token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Play()
|
||||
{
|
||||
currentTween.Stop();
|
||||
target.localScale = baseScale;
|
||||
target.localEulerAngles = baseEuler;
|
||||
target.localPosition = baseLocalPosition;
|
||||
|
||||
switch (effect)
|
||||
{
|
||||
case ButtonEffectType.None:
|
||||
break;
|
||||
case ButtonEffectType.Scale:
|
||||
currentTween = Tween.Scale(target, baseScale * scaleAmount, duration, ease, 2, CycleMode.Yoyo);
|
||||
break;
|
||||
case ButtonEffectType.PunchScale:
|
||||
currentTween = Tween.PunchScale(target, Vector3.one * (scaleAmount - 1f), duration);
|
||||
break;
|
||||
case ButtonEffectType.ShakePosition:
|
||||
currentTween = Tween.ShakeLocalPosition(target, Vector3.one * shakeStrength, duration);
|
||||
break;
|
||||
case ButtonEffectType.ShakeRotation:
|
||||
currentTween = Tween.ShakeLocalRotation(target, new Vector3(0f, 0f, rotationStrength), duration);
|
||||
break;
|
||||
case ButtonEffectType.Bounce:
|
||||
currentTween = Tween.Scale(target, baseScale * scaleAmount, duration, Ease.OutBounce, 2, CycleMode.Yoyo);
|
||||
break;
|
||||
case ButtonEffectType.Pulse:
|
||||
currentTween = Tween.Scale(target, baseScale * scaleAmount, duration * 0.5f, Ease.InOutSine, 4, CycleMode.Yoyo);
|
||||
break;
|
||||
case ButtonEffectType.Wobble:
|
||||
currentTween = Tween.LocalEulerAngles(target, baseEuler, baseEuler + new Vector3(0f, 0f, rotationStrength), duration * 0.25f, Ease.InOutSine, 4, CycleMode.Yoyo);
|
||||
break;
|
||||
case ButtonEffectType.Flip:
|
||||
currentTween = Tween.LocalEulerAngles(target, baseEuler, baseEuler + new Vector3(0f, 360f, 0f), duration, ease);
|
||||
break;
|
||||
case ButtonEffectType.Spin:
|
||||
currentTween = Tween.LocalEulerAngles(target, baseEuler, baseEuler + new Vector3(0f, 0f, 360f), duration, ease);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e5e02a6b9f322a4d893b3e45a3a2967
|
||||
@@ -5,7 +5,9 @@
|
||||
"GUID:6a0a834eb41764f12ba55c3fb04a40cb",
|
||||
"GUID:c1c03c0e5b2f4412b9f2be1c20d6a9b1",
|
||||
"GUID:b0214a6008ed146ff8f122a6a9c2f6cc",
|
||||
"GUID:68765d262e2128e4ab49c983f3411946"
|
||||
"GUID:68765d262e2128e4ab49c983f3411946",
|
||||
"GUID:80ecb87cae9c44d19824e70ea7229748",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Spine.Unity;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
@@ -7,10 +10,50 @@ namespace Darkmatter.Features.Mainmenu
|
||||
public class MainmenuView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Button playBtn;
|
||||
[SerializeField] private SkeletonGraphic mascotSkeletonGraphic;
|
||||
|
||||
[Header("Mascot Animations")]
|
||||
[SerializeField] private string jumpAnimation = "jump";
|
||||
[SerializeField] private string idleAnimation = "idle";
|
||||
[SerializeField] private string helloAnimation = "hello";
|
||||
[SerializeField] private float helloInterval = 5f;
|
||||
|
||||
public event Action OnPlayBtnClickedEvent;
|
||||
|
||||
private CancellationTokenSource helloCts;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
playBtn.onClick.AddListener(OnPlayBtnClicked);
|
||||
PlayMascotIntro();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
helloCts?.Cancel();
|
||||
helloCts?.Dispose();
|
||||
helloCts = null;
|
||||
}
|
||||
|
||||
private void PlayMascotIntro()
|
||||
{
|
||||
var state = mascotSkeletonGraphic.AnimationState;
|
||||
state.SetAnimation(0, jumpAnimation, false);
|
||||
state.AddAnimation(0, idleAnimation, true, 0f);
|
||||
|
||||
helloCts = CancellationTokenSource.CreateLinkedTokenSource(this.GetCancellationTokenOnDestroy());
|
||||
HelloLoopAsync(helloCts.Token).Forget();
|
||||
}
|
||||
|
||||
private async UniTaskVoid HelloLoopAsync(CancellationToken token)
|
||||
{
|
||||
var state = mascotSkeletonGraphic.AnimationState;
|
||||
while (!token.IsCancellationRequested)
|
||||
{
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(helloInterval), cancellationToken: token);
|
||||
state.SetAnimation(0, helloAnimation, false);
|
||||
state.AddAnimation(0, idleAnimation, true, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayBtnClicked()
|
||||
|
||||
Reference in New Issue
Block a user