/// /// SURGE FRAMEWORK /// Author: Bob Berkebile /// Email: bobb@pixelplacement.com /// /// Base class for tweens. /// /// using UnityEngine; using System; using Pixelplacement; #pragma warning disable 0168 namespace Pixelplacement.TweenSystem { public abstract class TweenBase { //Public Variables: public int targetInstanceID; public Tween.TweenType tweenType; //Public Properties: public Tween.TweenStatus Status {get; private set;} public float Duration {get; private set;} public AnimationCurve Curve {get; private set;} public Keyframe[] CurveKeys { get; private set; } public bool ObeyTimescale {get; private set;} public Action StartCallback {get; private set;} public Action CompleteCallback {get; private set;} public float Delay {get; private set;} public Tween.LoopType LoopType {get; private set;} public float Percentage {get; private set; } //Protected Variables: protected float elapsedTime = 0.0f; //Public Methods: /// /// Stop/pauses the tween. /// public void Stop () { Status = Tween.TweenStatus.Stopped; Tick (); } /// /// Starts or restarts a tween - interrupts a delay and allows a canceled or finished tween to restart. /// public void Start () { elapsedTime = 0.0f; if (Status == Tween.TweenStatus.Canceled || Status == Tween.TweenStatus.Finished || Status == Tween.TweenStatus.Stopped) { Status = Tween.TweenStatus.Running; Operation (0); Tween.Instance.ExecuteTween (this); } } /// /// Resumes a stopped/paused tween. /// public void Resume() { if (Status != Tween.TweenStatus.Stopped) return; if (Status == Tween.TweenStatus.Stopped) { Status = Tween.TweenStatus.Running; Tween.Instance.ExecuteTween(this); } } /// /// Rewind the tween. /// public void Rewind () { Cancel (); Operation (0); } /// /// Rewind the tween and stop. /// public void Cancel () { Status = Tween.TweenStatus.Canceled; Tick (); } /// /// Fast forward the tween and stop. /// public void Finish () { Status = Tween.TweenStatus.Finished; Tick (); } /// /// Used internally to update the tween and report status to the main system. /// public void Tick () { //stop where we are: if (Status == Tween.TweenStatus.Stopped) { CleanUp(); return; } //rewind operation and stop: if (Status == Tween.TweenStatus.Canceled) { Operation (0); Percentage = 0; CleanUp(); return; } //fast forward operation and stop: if (Status == Tween.TweenStatus.Finished) { Operation (1); Percentage = 1; if (CompleteCallback != null) CompleteCallback (); CleanUp(); return; } float progress = 0.0f; //calculate: if (ObeyTimescale) { elapsedTime += Time.deltaTime; }else{ elapsedTime += Time.unscaledDeltaTime; } progress = Math.Max(elapsedTime, 0f); //percentage: float percentage = Mathf.Min(progress / Duration, 1); //delayed? if (percentage == 0 && Status != Tween.TweenStatus.Delayed) Status = Tween.TweenStatus.Delayed; //running? if (percentage > 0 && Status == Tween.TweenStatus.Delayed) { if (SetStartValue ()) { if (StartCallback != null) StartCallback (); Status = Tween.TweenStatus.Running; }else{ CleanUp(); return; } } //evaluate: float curveValue = percentage; //using a curve? if (Curve != null && CurveKeys.Length > 0) curveValue = TweenUtilities.EvaluateCurve (Curve, percentage); //perform operation with minimal overhead of a try/catch to account for anything that has been destroyed while tweening: if (Status == Tween.TweenStatus.Running) { try { Operation (curveValue); Percentage = curveValue; } catch (Exception ex) { CleanUp(); return; } } //tween complete: if (percentage == 1) { if (CompleteCallback != null) { CompleteCallback(); } switch (LoopType) { case Tween.LoopType.Loop: Loop (); break; case Tween.LoopType.PingPong: PingPong (); break; default: Status = Tween.TweenStatus.Finished; CleanUp(); return; } } } //Private Methods: private void CleanUp() { if (Tween.activeTweens.Contains(this)) { Tween.activeTweens.Remove(this); } } //Protected Methods: /// /// Resets the start time. /// protected void ResetStartTime () { elapsedTime = -Delay; } /// /// Sets the essential properties that all tweens need and should be called from their constructor. If targetInstanceID is -1 then this tween won't interrupt tweens of the same type on the same target. /// protected void SetEssentials (Tween.TweenType tweenType, int targetInstanceID, float duration, float delay, bool obeyTimeScale, AnimationCurve curve, Tween.LoopType loop, Action startCallback, Action completeCallback) { this.tweenType = tweenType; this.targetInstanceID = targetInstanceID; if (delay > 0) Status = Tween.TweenStatus.Delayed; Duration = duration; Delay = delay; Curve = curve; CurveKeys = curve == null ? null : curve.keys; StartCallback = startCallback; CompleteCallback = completeCallback; LoopType = loop; ObeyTimescale = obeyTimeScale; ResetStartTime (); } //Abstract Methods: /// /// Override this method to carry out the initialization required for the tween. /// protected abstract bool SetStartValue (); /// /// Override this method to carry out the processing required for the tween. /// protected abstract void Operation (float percentage); /// /// Override this method to carry out a standard loop. /// public abstract void Loop (); /// /// Override this method to carry out a ping pong loop. /// public abstract void PingPong (); } }