using System; using System.Collections.Generic; using System.Diagnostics; using UnityEngine; namespace Tweening { public sealed class Tweener : MonoBehaviour { //[DebuggerBrowsable(DebuggerBrowsableState.Never)] public event Tweener.FinishedPlayingEventHandler FinishedPlaying; private void Awake() { this.IsPlaying = false; this.IsPaused = false; this._tracks.Sort((TweenerTrackBase a, TweenerTrackBase b) => a.Delay.CompareTo(b.Delay)); this.AnimationTime = this.CalcHighestEndTime(); } private void Start() { if (this._playOnStart) { this.Play(); } } private void Update() { if (!this.IsPlaying || this.IsPaused) { return; } if (this._time >= this.AnimationTime && this._loop) { this._time = 0f; this.UpdateTrackComponentValues(); } this._time += Time.deltaTime; this.UpdateTrackComponentValues(); if (this._time >= this.AnimationTime && !this._loop) { this.UpdateTrackComponentValues((!this.IsPlaybackReversed) ? this.AnimationTime : 0f); this.IsPlaying = false; if (this.FinishedPlaying != null) { this.FinishedPlaying(this); } } } public void Play() { this.Play(false, 0f); } public void PlayReverse() { this.Play(true, 0f); } public void PlayWithOffset(float offset) { if (this._loop) { offset %= this.AnimationTime; } else { offset = Mathf.Clamp(offset, 0f, this.AnimationTime); } this.Play(false, offset); } public void TogglePause() { this.IsPaused = !this.IsPaused; } public void Stop() { if (!this.IsPlaying) { UnityEngine.Debug.LogWarning("Tweener isn't playing."); return; } this.IsPlaying = false; } public void Reset(bool resetToEnd = false) { if (this.IsPlaying) { UnityEngine.Debug.LogWarning("Can't reset while playing."); return; } for (int i = this._tracks.Count - 1; i >= 0; i--) { this._tracks[i].ResetTrack(); } if (resetToEnd) { this.UpdateTrackComponentValues(this.CalcHighestEndTime()); } } public void StopAndReset(bool resetToEnd = false) { if (this.IsPlaying) { this.Stop(); } this.Reset(resetToEnd); } public bool IsPlaying { get; private set; } public bool IsPaused { get; private set; } public bool IsPlaybackReversed { get; private set; } public float AnimationTime { get; private set; } private void Play(bool playReversed, float offset) { if (this.IsPlaying) { UnityEngine.Debug.LogWarning("Tweener is already playing."); return; } this.IsPlaybackReversed = playReversed; this.IsPlaying = true; this.IsPaused = false; this._time = offset; this.AnimationTime = this.CalcHighestEndTime(); for (int i = this._tracks.Count - 1; i >= 0; i--) { this._tracks[i].ResetTrack(); } this.UpdateTrackComponentValues(); } private void UpdateTrackComponentValues() { this.UpdateTrackComponentValues((!this.IsPlaybackReversed) ? this._time : (this.AnimationTime - this._time)); } private void UpdateTrackComponentValues(float trackTime) { int count = this._tracks.Count; for (int i = 0; i < count; i++) { Tweener.UpdateComponentValue(this._tracks[i], trackTime); } } private static void UpdateComponentValue(TweenerTrackBase track, float time) { if (time >= track.Delay) { track.InitializeTrack(); WrapMode postWrapMode = track.Curve.postWrapMode; float time2; if (postWrapMode != WrapMode.Loop) { if (postWrapMode != WrapMode.PingPong) { time2 = Mathf.Clamp01((time - track.Delay) / track.Duration); } else { time2 = Mathf.PingPong((time - track.Delay) / track.Duration, 1f); } } else { time2 = (time - track.Delay) / track.Duration; } track.UpdateComponentValue(track.Curve.Evaluate(time2)); } } private float CalcHighestEndTime() { float num = 0f; int count = this._tracks.Count; for (int i = 0; i < count; i++) { num = Mathf.Max(num, this._tracks[i].EndTime); } return num; } [SerializeField] private bool _playOnStart; [SerializeField] private bool _loop; [SerializeField] private List _tracks; private float _time; public delegate void FinishedPlayingEventHandler(Tweener tweener); } }