2025-05-08 13:38:55 +08:00

133 lines
5.5 KiB
C#

#if PRIME_TWEEN_INSTALLED && UNITY_UGUI_INSTALLED
using PrimeTween;
using UnityEngine.UI;
#endif
using UnityEngine;
namespace PrimeTweenDemo {
public class Demo : MonoBehaviour {
#if PRIME_TWEEN_INSTALLED && UNITY_UGUI_INSTALLED
[SerializeField] AnimateAllType animateAllType; enum AnimateAllType { Sequence, Async, Coroutine }
[SerializeField] Slider sequenceTimelineSlider;
[SerializeField] Text pausedLabel;
[SerializeField] Button animateAllPartsButton;
[SerializeField] TypewriterAnimatorExample typewriterAnimatorExample;
[SerializeField] Animatable[] animatables;
[SerializeField] Wheels wheels;
[SerializeField, Range(0.5f, 5f)] float timeScale = 1;
bool isAnimatingWithCoroutineOrAsync;
public Sequence animateAllSequence;
void Awake() {
PrimeTweenConfig.SetTweensCapacity(100);
}
void OnEnable() {
sequenceTimelineSlider.fillRect.gameObject.SetActive(false);
sequenceTimelineSlider.onValueChanged.AddListener(SequenceTimelineSliderChanged);
}
void OnDisable() => sequenceTimelineSlider.onValueChanged.RemoveListener(SequenceTimelineSliderChanged);
void SequenceTimelineSliderChanged(float sliderValue) {
if (!notifySliderChanged) {
return;
}
if (!animateAllSequence.isAlive) {
wheels.OnClick();
}
animateAllSequence.isPaused = true;
animateAllSequence.progressTotal = sliderValue;
}
bool notifySliderChanged = true;
void UpdateSlider() {
var isSliderVisible = animateAllType == AnimateAllType.Sequence && !isAnimatingWithCoroutineOrAsync;
sequenceTimelineSlider.gameObject.SetActive(isSliderVisible);
if (!isSliderVisible) {
return;
}
pausedLabel.gameObject.SetActive(animateAllSequence.isAlive && animateAllSequence.isPaused);
var isSequenceAlive = animateAllSequence.isAlive;
sequenceTimelineSlider.handleRect.gameObject.SetActive(isSequenceAlive);
if (isSequenceAlive) {
notifySliderChanged = false;
sequenceTimelineSlider.value = animateAllSequence.progressTotal; // Unity 2018 doesn't have SetValueWithoutNotify(), so use notifySliderChanged instead
notifySliderChanged = true;
}
}
void Update() {
Time.timeScale = timeScale;
animateAllPartsButton.GetComponent<Image>().enabled = !isAnimatingWithCoroutineOrAsync;
animateAllPartsButton.GetComponentInChildren<Text>().enabled = !isAnimatingWithCoroutineOrAsync;
UpdateSlider();
}
public void AnimateAll(bool toEndValue) {
if (isAnimatingWithCoroutineOrAsync) {
return;
}
switch (animateAllType) {
case AnimateAllType.Sequence:
AnimateAllSequence(toEndValue);
break;
case AnimateAllType.Async:
AnimateAllAsync(toEndValue);
break;
case AnimateAllType.Coroutine:
StartCoroutine(AnimateAllCoroutine(toEndValue));
break;
}
}
/// Tweens and sequences can be grouped with and chained to other tweens and sequences.
/// The advantage of using this method instead of <see cref="AnimateAllAsync"/> and <see cref="AnimateAllCoroutine"/> is the ability to stop/complete/pause the combined sequence.
/// Also, this method doesn't generate garbage related to starting a coroutine or awaiting an async method.
void AnimateAllSequence(bool toEndValue) {
if (animateAllSequence.isAlive) {
animateAllSequence.isPaused = !animateAllSequence.isPaused;
return;
}
animateAllSequence = Sequence.Create();
#if TEXT_MESH_PRO_INSTALLED
animateAllSequence.Group(typewriterAnimatorExample.Animate());
#endif
float delay = 0f;
foreach (var animatable in animatables) {
animateAllSequence.Insert(delay, animatable.Animate(toEndValue));
delay += 0.6f;
}
}
/// Tweens and sequences can be awaited in async methods.
async void AnimateAllAsync(bool toEndValue) {
isAnimatingWithCoroutineOrAsync = true;
foreach (var animatable in animatables) {
await animatable.Animate(toEndValue);
}
isAnimatingWithCoroutineOrAsync = false;
}
/// Tweens and sequences can also be used in coroutines with the help of ToYieldInstruction() method.
System.Collections.IEnumerator AnimateAllCoroutine(bool toEndValue) {
isAnimatingWithCoroutineOrAsync = true;
foreach (var animatable in animatables) {
yield return animatable.Animate(toEndValue).ToYieldInstruction();
}
isAnimatingWithCoroutineOrAsync = false;
}
#else // PRIME_TWEEN_INSTALLED
void Awake() {
Debug.LogError("Please install PrimeTween via 'Assets/Plugins/PrimeTween/PrimeTweenInstaller'.");
#if !UNITY_2019_1_OR_NEWER
Debug.LogError("And add the 'PRIME_TWEEN_INSTALLED' define to the 'Project Settings/Player/Scripting Define Symbols' to run the Demo in Unity 2018.");
#endif
}
#endif
}
}