// Author: Daniele Giardini - http://www.demigiant.com // Created: 2014/05/07 14:05 // // License Copyright (c) Daniele Giardini. // This work is subject to the terms at http://dotween.demigiant.com/license.php #if COMPATIBLE using DOVector2 = DG.Tweening.Core.Surrogates.Vector2Wrapper; using DOVector3 = DG.Tweening.Core.Surrogates.Vector3Wrapper; using DOVector4 = DG.Tweening.Core.Surrogates.Vector4Wrapper; using DOQuaternion = DG.Tweening.Core.Surrogates.QuaternionWrapper; using DOColor = DG.Tweening.Core.Surrogates.ColorWrapper; #else using DOVector2 = UnityEngine.Vector2; using DOVector3 = UnityEngine.Vector3; using DOVector4 = UnityEngine.Vector4; using DOQuaternion = UnityEngine.Quaternion; using DOColor = UnityEngine.Color; #endif using System.Collections.Generic; using DG.Tweening.Core; using DG.Tweening.Core.Enums; using DG.Tweening.Plugins.Core; using DG.Tweening.Plugins.Options; using UnityEngine; namespace DG.Tweening { /// /// Main DOTween class. Contains static methods to create and control tweens in a generic way /// public class DOTween { /// DOTween's version public static readonly string Version = "1.0.765"; /////////////////////////////////////////////// // Options //////////////////////////////////// /// If TRUE (default) makes tweens slightly slower but safer, automatically taking care of a series of things /// (like targets becoming null while a tween is playing). /// Default: TRUE public static bool useSafeMode = true; /// If TRUE you will get a DOTween report when exiting play mode (only in the Editor). /// Useful to know how many max Tweeners and Sequences you reached and optimize your final project accordingly. /// Beware, this will slightly slow down your tweens while inside Unity Editor. /// Default: FALSE public static bool showUnityEditorReport = false; /// Global DOTween timeScale. /// Default: 1 public static float timeScale = 1; /// If TRUE, DOTween will use Time.smoothDeltaTime instead of Time.deltaTime for UpdateType.Normal and UpdateType.Late tweens /// (unless they're set as timeScaleIndependent, in which case this setting will be ignored). /// Setting this to TRUE will lead to smoother animations. /// Default: FALSE public static bool useSmoothDeltaTime; /// DOTween's log behaviour. /// Default: LogBehaviour.ErrorsOnly public static LogBehaviour logBehaviour { get { return _logBehaviour; } set { _logBehaviour = value; Debugger.SetLogPriority(_logBehaviour); } } static LogBehaviour _logBehaviour = LogBehaviour.ErrorsOnly; /// If TRUE draws path gizmos in Unity Editor (if the gizmos button is active). /// Deactivate this if you want to avoid gizmos overhead while in Unity Editor public static bool drawGizmos = true; /////////////////////////////////////////////// // Default options for Tweens ///////////////// /// Default updateType for new tweens. /// Default: UpdateType.Normal public static UpdateType defaultUpdateType = UpdateType.Normal; /// Sets whether Unity's timeScale should be taken into account by default or not. /// Default: false public static bool defaultTimeScaleIndependent = false; /// Default autoPlay behaviour for new tweens. /// Default: AutoPlay.All public static AutoPlay defaultAutoPlay = AutoPlay.All; /// Default autoKillOnComplete behaviour for new tweens. /// Default: TRUE public static bool defaultAutoKill = true; /// Default loopType applied to all new tweens. /// Default: LoopType.Restart public static LoopType defaultLoopType = LoopType.Restart; /// If TRUE all newly created tweens are set as recyclable, otherwise not. /// Default: FALSE public static bool defaultRecyclable; /// Default ease applied to all new Tweeners (not to Sequences which always have Ease.Linear as default). /// Default: Ease.InOutQuad public static Ease defaultEaseType = Ease.OutQuad; /// Default overshoot/amplitude used for eases /// Default: 1.70158f public static float defaultEaseOvershootOrAmplitude = 1.70158f; /// Default period used for eases /// Default: 0 public static float defaultEasePeriod = 0; internal static DOTweenComponent instance; // Assigned/removed by DOTweenComponent.Create/DestroyInstance internal static bool isUnityEditor; internal static bool isDebugBuild; internal static int maxActiveTweenersReached, maxActiveSequencesReached; // Controlled by DOTweenInspector if showUnityEditorReport is active internal static readonly List GizmosDelegates = new List(); // Can be used by other classes to call internal gizmo draw methods internal static bool initialized; // Can be set to false by DOTweenComponent OnDestroy internal static bool isQuitting; // Set by DOTweenComponent when the application is quitting #region Static Constructor static DOTween() { isUnityEditor = Application.isEditor; #if DEBUG isDebugBuild = true; #endif } #endregion #region Public Methods /// /// Must be called once, before the first ever DOTween call/reference, /// otherwise it will be called automatically and will use default options. /// Calling it a second time won't have any effect. /// You can chain SetCapacity to this method, to directly set the max starting size of Tweeners and Sequences: /// DOTween.Init(false, false, LogBehaviour.Default).SetCapacity(100, 20); /// /// If TRUE all new tweens will be set for recycling, meaning that when killed, /// instead of being destroyed, they will be put in a pool and reused instead of creating new tweens. This option allows you to avoid /// GC allocations by reusing tweens, but you will have to take care of tween references, since they might result active /// even if they were killed (since they might have been respawned and are now being used for other tweens). /// If you want to automatically set your tween references to NULL when a tween is killed /// you can use the OnKill callback like this: /// .OnKill(()=> myTweenReference = null) /// You can change this setting at any time by changing the static property, /// or you can set the recycling behaviour for each tween separately, using: /// SetRecyclable(bool recyclable) /// Default: FALSE /// If TRUE makes tweens slightly slower but safer, automatically taking care of a series of things /// (like targets becoming null while a tween is playing). /// You can change this setting at any time by changing the static property. /// Default: FALSE /// Type of logging to use. /// You can change this setting at any time by changing the static property. /// Default: ErrorsOnly public static IDOTweenInit Init(bool? recycleAllByDefault = null, bool? useSafeMode = null, LogBehaviour? logBehaviour = null) { if (initialized) return instance; if (!Application.isPlaying || isQuitting) return null; DOTweenSettings settings = Resources.Load(DOTweenSettings.AssetName) as DOTweenSettings; return Init(settings, recycleAllByDefault, useSafeMode, logBehaviour); } // Auto-init static void AutoInit() { DOTweenSettings settings = Resources.Load(DOTweenSettings.AssetName) as DOTweenSettings; Init(settings, null, null, null); } // Full init static IDOTweenInit Init(DOTweenSettings settings, bool? recycleAllByDefault, bool? useSafeMode, LogBehaviour? logBehaviour) { initialized = true; // Options if (recycleAllByDefault != null) DOTween.defaultRecyclable = (bool)recycleAllByDefault; if (useSafeMode != null) DOTween.useSafeMode = (bool)useSafeMode; if (logBehaviour != null) DOTween.logBehaviour = (LogBehaviour)logBehaviour; // Gameobject - also assign instance DOTweenComponent.Create(); // Assign settings if (settings != null) { if (useSafeMode == null) DOTween.useSafeMode = settings.useSafeMode; if (logBehaviour == null) DOTween.logBehaviour = settings.logBehaviour; if (recycleAllByDefault == null) DOTween.defaultRecyclable = settings.defaultRecyclable; DOTween.timeScale = settings.timeScale; DOTween.useSmoothDeltaTime = settings.useSmoothDeltaTime; DOTween.defaultRecyclable = recycleAllByDefault == null ? settings.defaultRecyclable : (bool)recycleAllByDefault; DOTween.showUnityEditorReport = settings.showUnityEditorReport; DOTween.drawGizmos = settings.drawGizmos; DOTween.defaultAutoPlay = settings.defaultAutoPlay; DOTween.defaultUpdateType = settings.defaultUpdateType; DOTween.defaultTimeScaleIndependent = settings.defaultTimeScaleIndependent; DOTween.defaultEaseType = settings.defaultEaseType; DOTween.defaultEaseOvershootOrAmplitude = settings.defaultEaseOvershootOrAmplitude; DOTween.defaultEasePeriod = settings.defaultEasePeriod; DOTween.defaultAutoKill = settings.defaultAutoKill; DOTween.defaultLoopType = settings.defaultLoopType; } // Log if (Debugger.logPriority >= 2) Debugger.Log("DOTween initialization (useSafeMode: " + DOTween.useSafeMode + ", recycling: " + (DOTween.defaultRecyclable ? "ON" : "OFF") + ", logBehaviour: " + DOTween.logBehaviour + ")"); return instance; } /// /// Directly sets the current max capacity of Tweeners and Sequences /// (meaning how many Tweeners and Sequences can be running at the same time), /// so that DOTween doesn't need to automatically increase them in case the max is reached /// (which might lead to hiccups when that happens). /// Sequences capacity must be less or equal to Tweeners capacity /// (if you pass a low Tweener capacity it will be automatically increased to match the Sequence's). /// Beware: use this method only when there are no tweens running. /// /// Max Tweeners capacity. /// Default: 200 /// Max Sequences capacity. /// Default: 50 public static void SetTweensCapacity(int tweenersCapacity, int sequencesCapacity) { TweenManager.SetCapacities(tweenersCapacity, sequencesCapacity); } /// /// Kills all tweens, clears all cached tween pools and plugins and resets the max Tweeners/Sequences capacities to the default values. /// /// If TRUE also destroys DOTween's gameObject and resets its initializiation, default settings and everything else /// (so that next time you use it it will need to be re-initialized) public static void Clear(bool destroy = false) { TweenManager.PurgeAll(); PluginsManager.PurgeAll(); if (!destroy) return; initialized = false; useSafeMode = false; showUnityEditorReport = false; drawGizmos = true; timeScale = 1; useSmoothDeltaTime = false; logBehaviour = LogBehaviour.ErrorsOnly; defaultEaseType = Ease.OutQuad; defaultEaseOvershootOrAmplitude = 1.70158f; defaultEasePeriod = 0; defaultUpdateType = UpdateType.Normal; defaultTimeScaleIndependent = false; defaultAutoPlay = AutoPlay.All; defaultLoopType = LoopType.Restart; defaultAutoKill = true; defaultRecyclable = false; maxActiveTweenersReached = maxActiveSequencesReached = 0; DOTweenComponent.DestroyInstance(); } /// /// Clears all cached tween pools. /// public static void ClearCachedTweens() { TweenManager.PurgePools(); } /// /// Checks all active tweens to find and remove eventually invalid ones (usually because their targets became NULL) /// and returns the total number of invalid tweens found and removed. /// Automatically called when loading a new scene if is TRUE. /// BEWARE: this is a slightly expensive operation so use it with care /// public static int Validate() { return TweenManager.Validate(); } #endregion // =================================================================================== // PUBLIC TWEEN CREATION METHODS ----------------------------------------------------- // Sadly can't make generic versions of default tweens with additional options // where the TO method doesn't contain the options param, otherwise the correct Option type won't be inferred. // So: overloads. Sigh. // Also, Unity has a bug which doesn't allow method overloading with its own implicitly casteable types (like Vector4 and Color) // and additional parameters, so in those cases I have to create overloads instead than using optionals. ARARGH! #region Tween TO /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static TweenerCore To(DOGetter getter, DOSetter setter, float endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static Tweener To(DOGetter getter, DOSetter setter, int endValue,float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static Tweener To(DOGetter getter, DOSetter setter, uint endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static Tweener To(DOGetter getter, DOSetter setter, long endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static Tweener To(DOGetter getter, DOSetter setter, ulong endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static TweenerCore To(DOGetter getter, DOSetter setter, string endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static TweenerCore To(DOGetter getter, DOSetter setter, Vector2 endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static TweenerCore To(DOGetter getter, DOSetter setter, Vector3 endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static TweenerCore To(DOGetter getter, DOSetter setter, Vector4 endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static TweenerCore To(DOGetter getter, DOSetter setter, Vector3 endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static TweenerCore To(DOGetter getter, DOSetter setter, Color endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static TweenerCore To(DOGetter getter, DOSetter setter, Rect endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static Tweener To(DOGetter getter, DOSetter setter, RectOffset endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } /// Tweens a property or field to the given value using a custom plugin /// The plugin to use. Each custom plugin implements a static Get() method /// you'll need to call to assign the correct plugin in the correct way, like this: /// CustomPlugin.Get() /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static TweenerCore To( ABSTweenPlugin plugin, DOGetter getter, DOSetter setter, T2 endValue, float duration ) where TPlugOptions : struct { return ApplyTo(getter, setter, endValue, duration, plugin); } /// Tweens only one axis of a Vector3 to the given value using default plugins. /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration /// The axis to tween public static TweenerCore ToAxis(DOGetter getter, DOSetter setter, float endValue, float duration, AxisConstraint axisConstraint = AxisConstraint.X) { TweenerCore t = ApplyTo(getter, setter, new Vector3(endValue, endValue, endValue), duration); t.plugOptions.axisConstraint = axisConstraint; return t; } /// Tweens only the alpha of a Color to the given value using default plugins /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end value to reachThe tween's duration public static Tweener ToAlpha(DOGetter getter, DOSetter setter, float endValue, float duration) { return ApplyTo(getter, setter, new Color(0, 0, 0, endValue), duration).SetOptions(true); } #endregion #region Special TOs (No FROMs) /// Tweens a virtual property from the given start to the given end value /// and implements a setter that allows to use that value with an external method or a lambda /// Example: /// To(MyMethod, 0, 12, 0.5f); /// Where MyMethod is a function that accepts a float parameter (which will be the result of the virtual tween) /// The action to perform with the tweened value /// The value to start from /// The end value to reach /// The duration of the virtual tween /// public static Tweener To(DOSetter setter, float startValue, float endValue, float duration) { float v = startValue; return To(() => v, x => { v = x; setter(v); }, endValue, duration) .NoFrom(); } /// Punches a Vector3 towards the given direction and then back to the starting one /// as if it was connected to the starting position via an elastic. /// This tween type generates some GC allocations at startup /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The direction and strength of the punch /// The duration of the tween /// Indicates how much will the punch vibrate /// Represents how much (0 to 1) the vector will go beyond the starting position when bouncing backwards. /// 1 creates a full oscillation between the direction and the opposite decaying direction, /// while 0 oscillates only between the starting position and the decaying direction public static TweenerCore Punch(DOGetter getter, DOSetter setter, Vector3 direction, float duration, int vibrato = 10, float elasticity = 1) { if (elasticity > 1) elasticity = 1; else if (elasticity < 0) elasticity = 0; float strength = direction.magnitude; int totIterations = (int)(vibrato * duration); if (totIterations < 2) totIterations = 2; float decayXTween = strength / totIterations; // Calculate and store the duration of each tween float[] tDurations = new float[totIterations]; float sum = 0; for (int i = 0; i < totIterations; ++i) { float iterationPerc = (i + 1) / (float)totIterations; float tDuration = duration * iterationPerc; sum += tDuration; tDurations[i] = tDuration; } float tDurationMultiplier = duration / sum; // Multiplier that allows the sum of tDurations to equal the set duration for (int i = 0; i < totIterations; ++i) tDurations[i] = tDurations[i] * tDurationMultiplier; // Create the tween Vector3[] tos = new Vector3[totIterations]; for (int i = 0; i < totIterations; ++i) { if (i < totIterations - 1) { if (i == 0) tos[i] = direction; else if (i % 2 != 0) tos[i] = -Vector3.ClampMagnitude(direction, strength * elasticity); else tos[i] = Vector3.ClampMagnitude(direction, strength); strength -= decayXTween; } else tos[i] = Vector3.zero; } return ToArray(getter, setter, tos, tDurations) .NoFrom() .SetSpecialStartupMode(SpecialStartupMode.SetPunch); } /// Shakes a Vector3 with the given values. /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The duration of the tween /// The shake strength /// Indicates how much will the shake vibrate /// Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). /// Setting it to 0 will shake along a single direction and behave like a random punch. /// If TRUE only shakes on the X Y axis (looks better with things like cameras). public static TweenerCore Shake(DOGetter getter, DOSetter setter, float duration, float strength = 3, int vibrato = 10, float randomness = 90, bool ignoreZAxis = true ) { return Shake(getter, setter, duration, new Vector3(strength, strength, strength), vibrato, randomness, ignoreZAxis, false); } /// Shakes a Vector3 with the given values. /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The duration of the tween /// The shake strength on each axis /// Indicates how much will the shake vibrate /// Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). /// Setting it to 0 will shake along a single direction and behave like a random punch. public static TweenerCore Shake(DOGetter getter, DOSetter setter, float duration, Vector3 strength, int vibrato = 10, float randomness = 90 ) { return Shake(getter, setter, duration, strength, vibrato, randomness, false, true); } static TweenerCore Shake(DOGetter getter, DOSetter setter, float duration, Vector3 strength, int vibrato, float randomness, bool ignoreZAxis, bool vectorBased ) { float shakeMagnitude = vectorBased ? strength.magnitude : strength.x; int totIterations = (int)(vibrato * duration); if (totIterations < 2) totIterations = 2; float decayXTween = shakeMagnitude / totIterations; // Calculate and store the duration of each tween float[] tDurations = new float[totIterations]; float sum = 0; for (int i = 0; i < totIterations; ++i) { float iterationPerc = (i + 1) / (float)totIterations; float tDuration = duration * iterationPerc; sum += tDuration; tDurations[i] = tDuration; } float tDurationMultiplier = duration / sum; // Multiplier that allows the sum of tDurations to equal the set duration for (int i = 0; i < totIterations; ++i) tDurations[i] = tDurations[i] * tDurationMultiplier; // Create the tween float ang = UnityEngine.Random.Range(0f, 360f); Vector3[] tos = new Vector3[totIterations]; for (int i = 0; i < totIterations; ++i) { if (i < totIterations - 1) { if (i > 0) ang = ang - 180 + UnityEngine.Random.Range(-randomness, randomness); if (vectorBased) { Quaternion rndQuaternion = Quaternion.AngleAxis(UnityEngine.Random.Range(-randomness, randomness), Vector3.up); Vector3 to = rndQuaternion * Utils.Vector3FromAngle(ang, shakeMagnitude); to.x = Vector3.ClampMagnitude(to, strength.x).x; to.y = Vector3.ClampMagnitude(to, strength.y).y; to.z = Vector3.ClampMagnitude(to, strength.z).z; tos[i] = to; shakeMagnitude -= decayXTween; strength = Vector3.ClampMagnitude(strength, shakeMagnitude); } else { if (ignoreZAxis) { tos[i] = Utils.Vector3FromAngle(ang, shakeMagnitude); } else { Quaternion rndQuaternion = Quaternion.AngleAxis(UnityEngine.Random.Range(-randomness, randomness), Vector3.up); tos[i] = rndQuaternion * Utils.Vector3FromAngle(ang, shakeMagnitude); } shakeMagnitude -= decayXTween; } } else tos[i] = Vector3.zero; } return ToArray(getter, setter, tos, tDurations) .NoFrom().SetSpecialStartupMode(SpecialStartupMode.SetShake); } /// Tweens a property or field to the given values using default plugins. /// Ease is applied between each segment and not as a whole. /// This tween type generates some GC allocations at startup /// A getter for the field or property to tween. /// Example usage with lambda:()=> myProperty /// A setter for the field or property to tween /// Example usage with lambda:x=> myProperty = x /// The end values to reach for each segment. This array must have the same length as durations /// The duration of each segment. This array must have the same length as endValues public static TweenerCore ToArray(DOGetter getter, DOSetter setter, Vector3[] endValues, float[] durations) { int len = durations.Length; if (len != endValues.Length) { Debugger.LogError("To Vector3 array tween: endValues and durations arrays must have the same length"); return null; } // Clone the arrays Vector3[] endValuesClone = new Vector3[len]; float[] durationsClone = new float[len]; for (int i = 0; i < len; i++) { endValuesClone[i] = endValues[i]; durationsClone[i] = durations[i]; } float totDuration = 0; for (int i = 0; i < len; ++i) totDuration += durationsClone[i]; TweenerCore t = ApplyTo(getter, setter, endValuesClone, totDuration) .NoFrom(); t.plugOptions.durations = durationsClone; return t; } #endregion #region Special TOs (INTERNAL) internal static TweenerCore To(DOGetter getter, DOSetter setter, Color2 endValue, float duration) { return ApplyTo(getter, setter, endValue, duration); } #endregion #region Tween SEQUENCE /// /// Returns a new to be used for tween groups /// public static Sequence Sequence() { InitCheck(); Sequence sequence = TweenManager.GetSequence(); Tweening.Sequence.Setup(sequence); return sequence; } #endregion ///////////////////////////////////////////////////////////////////// // OTHER STUFF ////////////////////////////////////////////////////// #region Play Operations /// Completes all tweens and returns the number of actual tweens completed /// (meaning tweens that don't have infinite loops and were not already complete) public static int CompleteAll() { return TweenManager.FilteredOperation(OperationType.Complete, FilterType.All, null, false, 0); } /// Completes all tweens with the given ID or target and returns the number of actual tweens completed /// (meaning the tweens that don't have infinite loops and were not already complete) public static int Complete(object targetOrId) { if (targetOrId == null) return 0; return TweenManager.FilteredOperation(OperationType.Complete, FilterType.TargetOrId, targetOrId, false, 0); } // Used internally to complete a tween and return only the number of killed tweens instead than just the completed ones // (necessary for Kill(complete) operation. Sets optionalBool to TRUE) internal static int CompleteAndReturnKilledTot() { return TweenManager.FilteredOperation(OperationType.Complete, FilterType.All, null, true, 0); } internal static int CompleteAndReturnKilledTot(object targetOrId) { if (targetOrId == null) return 0; return TweenManager.FilteredOperation(OperationType.Complete, FilterType.TargetOrId, targetOrId, true, 0); } /// Flips all tweens (changing their direction to forward if it was backwards and viceversa), /// then returns the number of actual tweens flipped public static int FlipAll() { return TweenManager.FilteredOperation(OperationType.Flip, FilterType.All, null, false, 0); } /// Flips the tweens with the given ID or target (changing their direction to forward if it was backwards and viceversa), /// then returns the number of actual tweens flipped public static int Flip(object targetOrId) { if (targetOrId == null) return 0; return TweenManager.FilteredOperation(OperationType.Flip, FilterType.TargetOrId, targetOrId, false, 0); } /// Sends all tweens to the given position (calculating also eventual loop cycles) and returns the actual tweens involved public static int GotoAll(float to, bool andPlay = false) { return TweenManager.FilteredOperation(OperationType.Goto, FilterType.All, null, andPlay, to); } /// Sends all tweens with the given ID or target to the given position (calculating also eventual loop cycles) /// and returns the actual tweens involved public static int Goto(object targetOrId, float to, bool andPlay = false) { if (targetOrId == null) return 0; return TweenManager.FilteredOperation(OperationType.Goto, FilterType.TargetOrId, targetOrId, andPlay, to); } /// Kills all tweens and returns the number of actual tweens killed /// If TRUE completes the tweens before killing them public static int KillAll(bool complete = false) { int tot = complete ? CompleteAndReturnKilledTot() : 0; return tot + TweenManager.DespawnAll(); } /// Kills all tweens with the given ID or target and returns the number of actual tweens killed /// If TRUE completes the tweens before killing them public static int Kill(object targetOrId, bool complete = false) { if (targetOrId == null) return 0; int tot = complete ? CompleteAndReturnKilledTot(targetOrId) : 0; return tot + TweenManager.FilteredOperation(OperationType.Despawn, FilterType.TargetOrId, targetOrId, false, 0); } /// Pauses all tweens and returns the number of actual tweens paused public static int PauseAll() { return TweenManager.FilteredOperation(OperationType.Pause, FilterType.All, null, false, 0); } /// Pauses all tweens with the given ID or target and returns the number of actual tweens paused /// (meaning the tweens that were actually playing and have been paused) public static int Pause(object targetOrId) { if (targetOrId == null) return 0; return TweenManager.FilteredOperation(OperationType.Pause, FilterType.TargetOrId, targetOrId, false, 0); } /// Plays all tweens and returns the number of actual tweens played /// (meaning tweens that were not already playing or complete) public static int PlayAll() { return TweenManager.FilteredOperation(OperationType.Play, FilterType.All, null, false, 0); } /// Plays all tweens with the given ID or target and returns the number of actual tweens played /// (meaning the tweens that were not already playing or complete) public static int Play(object targetOrId) { if (targetOrId == null) return 0; return TweenManager.FilteredOperation(OperationType.Play, FilterType.TargetOrId, targetOrId, false, 0); } /// Plays all tweens with the given target and the given ID, and returns the number of actual tweens played /// (meaning the tweens that were not already playing or complete) public static int Play(object target, object id) { if (target == null || id == null) return 0; return TweenManager.FilteredOperation(OperationType.Play, FilterType.TargetAndId, id, false, 0, target); } /// Plays backwards all tweens and returns the number of actual tweens played /// (meaning tweens that were not already started, playing backwards or rewinded) public static int PlayBackwardsAll() { return TweenManager.FilteredOperation(OperationType.PlayBackwards, FilterType.All, null, false, 0); } /// Plays backwards all tweens with the given ID or target and returns the number of actual tweens played /// (meaning the tweens that were not already started, playing backwards or rewinded) public static int PlayBackwards(object targetOrId) { if (targetOrId == null) return 0; return TweenManager.FilteredOperation(OperationType.PlayBackwards, FilterType.TargetOrId, targetOrId, false, 0); } /// Plays forward all tweens and returns the number of actual tweens played /// (meaning tweens that were not already playing forward or complete) public static int PlayForwardAll() { return TweenManager.FilteredOperation(OperationType.PlayForward, FilterType.All, null, false, 0); } /// Plays forward all tweens with the given ID or target and returns the number of actual tweens played /// (meaning the tweens that were not already playing forward or complete) public static int PlayForward(object targetOrId) { if (targetOrId == null) return 0; return TweenManager.FilteredOperation(OperationType.PlayForward, FilterType.TargetOrId, targetOrId, false, 0); } /// Restarts all tweens, then returns the number of actual tweens restarted public static int RestartAll(bool includeDelay = true) { return TweenManager.FilteredOperation(OperationType.Restart, FilterType.All, null, includeDelay, 0); } /// Restarts all tweens with the given ID or target, then returns the number of actual tweens restarted public static int Restart(object targetOrId, bool includeDelay = true) { if (targetOrId == null) return 0; return TweenManager.FilteredOperation(OperationType.Restart, FilterType.TargetOrId, targetOrId, includeDelay, 0); } /// Restarts all tweens with the given target and the given ID, and returns the number of actual tweens played /// (meaning the tweens that were not already playing or complete) public static int Restart(object target, object id, bool includeDelay = true) { if (target == null || id == null) return 0; return TweenManager.FilteredOperation(OperationType.Restart, FilterType.TargetAndId, id, includeDelay, 0, target); } /// Rewinds and pauses all tweens, then returns the number of actual tweens rewinded /// (meaning tweens that were not already rewinded) public static int RewindAll(bool includeDelay = true) { return TweenManager.FilteredOperation(OperationType.Rewind, FilterType.All, null, includeDelay, 0); } /// Rewinds and pauses all tweens with the given ID or target, then returns the number of actual tweens rewinded /// (meaning the tweens that were not already rewinded) public static int Rewind(object targetOrId, bool includeDelay = true) { if (targetOrId == null) return 0; return TweenManager.FilteredOperation(OperationType.Rewind, FilterType.TargetOrId, targetOrId, includeDelay, 0); } /// Toggles the play state of all tweens and returns the number of actual tweens toggled /// (meaning tweens that could be played or paused, depending on the toggle state) public static int TogglePauseAll() { return TweenManager.FilteredOperation(OperationType.TogglePause, FilterType.All, null, false, 0); } /// Toggles the play state of all tweens with the given ID or target and returns the number of actual tweens toggled /// (meaning the tweens that could be played or paused, depending on the toggle state) public static int TogglePause(object targetOrId) { if (targetOrId == null) return 0; return TweenManager.FilteredOperation(OperationType.TogglePause, FilterType.TargetOrId, targetOrId, false, 0); } #endregion #region Global Info Getters /// /// Returns TRUE if a tween with the given ID or target is active (regardless if it's playing or not). /// You can also use this to know if a shortcut tween is active for a given target. /// Example: /// transform.DOMoveX(45, 1); // transform is automatically added as the tween target /// DOTween.IsTweening(transform); // Returns true /// public static bool IsTweening(object targetOrId) { return TweenManager.FilteredOperation(OperationType.IsTweening, FilterType.TargetOrId, targetOrId, false, 0) > 0; } /// /// Returns the total number of active and playing tweens. /// A tween is considered as playing even if its delay is actually playing /// public static int TotalPlayingTweens() { return TweenManager.TotalPlayingTweens(); } /// /// Returns a list of all active tweens in a playing state. /// Returns NULL if there are no active playing tweens. /// Beware: each time you call this method a new list is generated, so use it for debug only /// public static List PlayingTweens() { return TweenManager.GetActiveTweens(true); } /// /// Returns a list of all active tweens in a paused state. /// Returns NULL if there are no active paused tweens. /// Beware: each time you call this method a new list is generated, so use it for debug only /// public static List PausedTweens() { return TweenManager.GetActiveTweens(false); } /// /// Returns a list of all active tweens with the given id. /// Returns NULL if there are no active tweens with the given id. /// Beware: each time you call this method a new list is generated /// If TRUE returns only the tweens with the given ID that are currently playing /// public static List TweensById(object id, bool playingOnly = false) { if (id == null) return null; return TweenManager.GetTweensById(id, playingOnly); } /// /// Returns a list of all active tweens with the given target. /// Returns NULL if there are no active tweens with the given target. /// Beware: each time you call this method a new list is generated /// If TRUE returns only the tweens with the given target that are currently playing /// public static List TweensByTarget(object target, bool playingOnly = false) { return TweenManager.GetTweensByTarget(target, playingOnly); } #endregion // =================================================================================== // METHODS --------------------------------------------------------------------------- static void InitCheck() { if (initialized || !Application.isPlaying || isQuitting) return; AutoInit(); } static TweenerCore ApplyTo( DOGetter getter, DOSetter setter, T2 endValue, float duration, ABSTweenPlugin plugin = null ) where TPlugOptions : struct { InitCheck(); TweenerCore tweener = TweenManager.GetTweener(); if (!Tweener.Setup(tweener, getter, setter, endValue, duration, plugin)) { TweenManager.Despawn(tweener); return null; } return tweener; } } }