// Author: Daniele Giardini - http://www.demigiant.com // Created: 2018/07/13 #if true && (UNITY_4_6 || UNITY_5 || UNITY_2017_1_OR_NEWER) // MODULE_MARKER using System; using UnityEngine; using UnityEngine.UI; using DG.Tweening.Core; using DG.Tweening.Core.Enums; #pragma warning disable 1591 namespace DG.Tweening { public static class DOTweenModuleUI { #region Shortcuts #region CanvasGroup /// Tweens a CanvasGroup's alpha color to the given value. /// Also stores the canvasGroup as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOFade(this CanvasGroup target, float endValue, float duration) { return DOTween.To(() => target.alpha, x => target.alpha = x, endValue, duration) .SetTarget(target); } #endregion #region Graphic /// Tweens an Graphic's color to the given value. /// Also stores the image as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOColor(this Graphic target, Color endValue, float duration) { return DOTween.To(() => target.color, x => target.color = x, endValue, duration).SetTarget(target); } /// Tweens an Graphic's alpha color to the given value. /// Also stores the image as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOFade(this Graphic target, float endValue, float duration) { return DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration) .SetTarget(target); } #endregion #region Image /// Tweens an Image's color to the given value. /// Also stores the image as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOColor(this Image target, Color endValue, float duration) { return DOTween.To(() => target.color, x => target.color = x, endValue, duration).SetTarget(target); } /// Tweens an Image's alpha color to the given value. /// Also stores the image as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOFade(this Image target, float endValue, float duration) { return DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration) .SetTarget(target); } /// Tweens an Image's fillAmount to the given value. /// Also stores the image as the tween's target so it can be used for filtered operations /// The end value to reach (0 to 1)The duration of the tween public static Tweener DOFillAmount(this Image target, float endValue, float duration) { if (endValue > 1) endValue = 1; else if (endValue < 0) endValue = 0; return DOTween.To(() => target.fillAmount, x => target.fillAmount = x, endValue, duration) .SetTarget(target); } /// Tweens an Image's colors using the given gradient /// (NOTE 1: only uses the colors of the gradient, not the alphas - NOTE 2: creates a Sequence, not a Tweener). /// Also stores the image as the tween's target so it can be used for filtered operations /// The gradient to useThe duration of the tween public static Sequence DOGradientColor(this Image target, Gradient gradient, float duration) { Sequence s = DOTween.Sequence(); GradientColorKey[] colors = gradient.colorKeys; int len = colors.Length; for (int i = 0; i < len; ++i) { GradientColorKey c = colors[i]; if (i == 0 && c.time <= 0) { target.color = c.color; continue; } float colorDuration = i == len - 1 ? duration - s.Duration(false) // Verifies that total duration is correct : duration * (i == 0 ? c.time : c.time - colors[i - 1].time); s.Append(target.DOColor(c.color, colorDuration).SetEase(Ease.Linear)); } return s; } #endregion #region LayoutElement /// Tweens an LayoutElement's flexibleWidth/Height to the given value. /// Also stores the LayoutElement as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOFlexibleSize(this LayoutElement target, Vector2 endValue, float duration, bool snapping = false) { return DOTween.To(() => new Vector2(target.flexibleWidth, target.flexibleHeight), x => { target.flexibleWidth = x.x; target.flexibleHeight = x.y; }, endValue, duration) .SetOptions(snapping).SetTarget(target); } /// Tweens an LayoutElement's minWidth/Height to the given value. /// Also stores the LayoutElement as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOMinSize(this LayoutElement target, Vector2 endValue, float duration, bool snapping = false) { return DOTween.To(() => new Vector2(target.minWidth, target.minHeight), x => { target.minWidth = x.x; target.minHeight = x.y; }, endValue, duration) .SetOptions(snapping).SetTarget(target); } /// Tweens an LayoutElement's preferredWidth/Height to the given value. /// Also stores the LayoutElement as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOPreferredSize(this LayoutElement target, Vector2 endValue, float duration, bool snapping = false) { return DOTween.To(() => new Vector2(target.preferredWidth, target.preferredHeight), x => { target.preferredWidth = x.x; target.preferredHeight = x.y; }, endValue, duration) .SetOptions(snapping).SetTarget(target); } #endregion #region Outline /// Tweens a Outline's effectColor to the given value. /// Also stores the Outline as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOColor(this Outline target, Color endValue, float duration) { return DOTween.To(() => target.effectColor, x => target.effectColor = x, endValue, duration).SetTarget(target); } /// Tweens a Outline's effectColor alpha to the given value. /// Also stores the Outline as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOFade(this Outline target, float endValue, float duration) { return DOTween.ToAlpha(() => target.effectColor, x => target.effectColor = x, endValue, duration) .SetTarget(target); } /// Tweens a Outline's effectDistance to the given value. /// Also stores the Outline as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOScale(this Outline target, Vector2 endValue, float duration) { return DOTween.To(() => target.effectDistance, x => target.effectDistance = x, endValue, duration) .SetTarget(target); } #endregion #region RectTransform /// Tweens a RectTransform's anchoredPosition to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOAnchorPos(this RectTransform target, Vector2 endValue, float duration, bool snapping = false) { return DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, endValue, duration) .SetOptions(snapping).SetTarget(target); } /// Tweens a RectTransform's anchoredPosition X to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOAnchorPosX(this RectTransform target, float endValue, float duration, bool snapping = false) { return DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(endValue, 0), duration) .SetOptions(AxisConstraint.X, snapping).SetTarget(target); } /// Tweens a RectTransform's anchoredPosition Y to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOAnchorPosY(this RectTransform target, float endValue, float duration, bool snapping = false) { return DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(0, endValue), duration) .SetOptions(AxisConstraint.Y, snapping).SetTarget(target); } /// Tweens a RectTransform's anchoredPosition3D to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOAnchorPos3D(this RectTransform target, Vector3 endValue, float duration, bool snapping = false) { return DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, endValue, duration) .SetOptions(snapping).SetTarget(target); } /// Tweens a RectTransform's anchoredPosition3D X to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOAnchorPos3DX(this RectTransform target, float endValue, float duration, bool snapping = false) { return DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, new Vector3(endValue, 0, 0), duration) .SetOptions(AxisConstraint.X, snapping).SetTarget(target); } /// Tweens a RectTransform's anchoredPosition3D Y to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOAnchorPos3DY(this RectTransform target, float endValue, float duration, bool snapping = false) { return DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, new Vector3(0, endValue, 0), duration) .SetOptions(AxisConstraint.Y, snapping).SetTarget(target); } /// Tweens a RectTransform's anchoredPosition3D Z to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOAnchorPos3DZ(this RectTransform target, float endValue, float duration, bool snapping = false) { return DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, new Vector3(0, 0, endValue), duration) .SetOptions(AxisConstraint.Z, snapping).SetTarget(target); } /// Tweens a RectTransform's anchorMax to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOAnchorMax(this RectTransform target, Vector2 endValue, float duration, bool snapping = false) { return DOTween.To(() => target.anchorMax, x => target.anchorMax = x, endValue, duration) .SetOptions(snapping).SetTarget(target); } /// Tweens a RectTransform's anchorMin to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOAnchorMin(this RectTransform target, Vector2 endValue, float duration, bool snapping = false) { return DOTween.To(() => target.anchorMin, x => target.anchorMin = x, endValue, duration) .SetOptions(snapping).SetTarget(target); } /// Tweens a RectTransform's pivot to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOPivot(this RectTransform target, Vector2 endValue, float duration) { return DOTween.To(() => target.pivot, x => target.pivot = x, endValue, duration) .SetTarget(target); } /// Tweens a RectTransform's pivot X to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOPivotX(this RectTransform target, float endValue, float duration) { return DOTween.To(() => target.pivot, x => target.pivot = x, new Vector2(endValue, 0), duration) .SetOptions(AxisConstraint.X).SetTarget(target); } /// Tweens a RectTransform's pivot Y to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOPivotY(this RectTransform target, float endValue, float duration) { return DOTween.To(() => target.pivot, x => target.pivot = x, new Vector2(0, endValue), duration) .SetOptions(AxisConstraint.Y).SetTarget(target); } /// Tweens a RectTransform's sizeDelta to the given value. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOSizeDelta(this RectTransform target, Vector2 endValue, float duration, bool snapping = false) { return DOTween.To(() => target.sizeDelta, x => target.sizeDelta = x, endValue, duration) .SetOptions(snapping).SetTarget(target); } /// Punches a RectTransform's anchoredPosition towards the given direction and then back to the starting one /// as if it was connected to the starting position via an elastic. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The direction and strength of the punch (added to the RectTransform's current position) /// 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 punch direction and the opposite direction, /// while 0 oscillates only between the punch and the start position /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOPunchAnchorPos(this RectTransform target, Vector2 punch, float duration, int vibrato = 10, float elasticity = 1, bool snapping = false) { return DOTween.Punch(() => target.anchoredPosition, x => target.anchoredPosition = x, punch, duration, vibrato, elasticity) .SetTarget(target).SetOptions(snapping); } /// Shakes a RectTransform's anchoredPosition with the given values. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// 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. /// If TRUE the tween will smoothly snap all values to integers /// If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not public static Tweener DOShakeAnchorPos(this RectTransform target, float duration, float strength = 100, int vibrato = 10, float randomness = 90, bool snapping = false, bool fadeOut = true) { return DOTween.Shake(() => target.anchoredPosition, x => target.anchoredPosition = x, duration, strength, vibrato, randomness, true, fadeOut) .SetTarget(target).SetSpecialStartupMode(SpecialStartupMode.SetShake).SetOptions(snapping); } /// Shakes a RectTransform's anchoredPosition with the given values. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// 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. /// If TRUE the tween will smoothly snap all values to integers /// If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not public static Tweener DOShakeAnchorPos(this RectTransform target, float duration, Vector2 strength, int vibrato = 10, float randomness = 90, bool snapping = false, bool fadeOut = true) { return DOTween.Shake(() => target.anchoredPosition, x => target.anchoredPosition = x, duration, strength, vibrato, randomness, fadeOut) .SetTarget(target).SetSpecialStartupMode(SpecialStartupMode.SetShake).SetOptions(snapping); } #region Special /// Tweens a RectTransform's anchoredPosition to the given value, while also applying a jump effect along the Y axis. /// Returns a Sequence instead of a Tweener. /// Also stores the RectTransform as the tween's target so it can be used for filtered operations /// The end value to reach /// Power of the jump (the max height of the jump is represented by this plus the final Y offset) /// Total number of jumps /// The duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Sequence DOJumpAnchorPos(this RectTransform target, Vector2 endValue, float jumpPower, int numJumps, float duration, bool snapping = false) { if (numJumps < 1) numJumps = 1; float startPosY = 0; float offsetY = -1; bool offsetYSet = false; // Separate Y Tween so we can elaborate elapsedPercentage on that insted of on the Sequence // (in case users add a delay or other elements to the Sequence) Sequence s = DOTween.Sequence(); Tween yTween = DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(0, jumpPower), duration / (numJumps * 2)) .SetOptions(AxisConstraint.Y, snapping).SetEase(Ease.OutQuad).SetRelative() .SetLoops(numJumps * 2, LoopType.Yoyo) .OnStart(()=> startPosY = target.anchoredPosition.y); s.Append(DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(endValue.x, 0), duration) .SetOptions(AxisConstraint.X, snapping).SetEase(Ease.Linear) ).Join(yTween) .SetTarget(target).SetEase(DOTween.defaultEaseType); s.OnUpdate(() => { if (!offsetYSet) { offsetYSet = true; offsetY = s.isRelative ? endValue.y : endValue.y - startPosY; } Vector2 pos = target.anchoredPosition; pos.y += DOVirtual.EasedValue(0, offsetY, s.ElapsedDirectionalPercentage(), Ease.OutQuad); target.anchoredPosition = pos; }); return s; } #endregion #endregion #region ScrollRect /// Tweens a ScrollRect's horizontal/verticalNormalizedPosition to the given value. /// Also stores the ScrollRect as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DONormalizedPos(this ScrollRect target, Vector2 endValue, float duration, bool snapping = false) { return DOTween.To(() => new Vector2(target.horizontalNormalizedPosition, target.verticalNormalizedPosition), x => { target.horizontalNormalizedPosition = x.x; target.verticalNormalizedPosition = x.y; }, endValue, duration) .SetOptions(snapping).SetTarget(target); } /// Tweens a ScrollRect's horizontalNormalizedPosition to the given value. /// Also stores the ScrollRect as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOHorizontalNormalizedPos(this ScrollRect target, float endValue, float duration, bool snapping = false) { return DOTween.To(() => target.horizontalNormalizedPosition, x => target.horizontalNormalizedPosition = x, endValue, duration) .SetOptions(snapping).SetTarget(target); } /// Tweens a ScrollRect's verticalNormalizedPosition to the given value. /// Also stores the ScrollRect as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOVerticalNormalizedPos(this ScrollRect target, float endValue, float duration, bool snapping = false) { return DOTween.To(() => target.verticalNormalizedPosition, x => target.verticalNormalizedPosition = x, endValue, duration) .SetOptions(snapping).SetTarget(target); } #endregion #region Slider /// Tweens a Slider's value to the given value. /// Also stores the Slider as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween /// If TRUE the tween will smoothly snap all values to integers public static Tweener DOValue(this Slider target, float endValue, float duration, bool snapping = false) { return DOTween.To(() => target.value, x => target.value = x, endValue, duration) .SetOptions(snapping).SetTarget(target); } #endregion #region Text /// Tweens a Text's color to the given value. /// Also stores the Text as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOColor(this Text target, Color endValue, float duration) { return DOTween.To(() => target.color, x => target.color = x, endValue, duration).SetTarget(target); } /// Tweens a Text's alpha color to the given value. /// Also stores the Text as the tween's target so it can be used for filtered operations /// The end value to reachThe duration of the tween public static Tweener DOFade(this Text target, float endValue, float duration) { return DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration) .SetTarget(target); } /// Tweens a Text's text to the given value. /// Also stores the Text as the tween's target so it can be used for filtered operations /// The end string to tween toThe duration of the tween /// If TRUE (default), rich text will be interpreted correctly while animated, /// otherwise all tags will be considered as normal text /// The type of scramble mode to use, if any /// A string containing the characters to use for scrambling. /// Use as many characters as possible (minimum 10) because DOTween uses a fast scramble mode which gives better results with more characters. /// Leave it to NULL (default) to use default ones public static Tweener DOText(this Text target, string endValue, float duration, bool richTextEnabled = true, ScrambleMode scrambleMode = ScrambleMode.None, string scrambleChars = null) { return DOTween.To(() => target.text, x => target.text = x, endValue, duration) .SetOptions(richTextEnabled, scrambleMode, scrambleChars) .SetTarget(target); } #endregion #region Blendables #region Graphic /// Tweens a Graphic's color to the given value, /// in a way that allows other DOBlendableColor tweens to work together on the same target, /// instead than fight each other as multiple DOColor would do. /// Also stores the Graphic as the tween's target so it can be used for filtered operations /// The value to tween toThe duration of the tween public static Tweener DOBlendableColor(this Graphic target, Color endValue, float duration) { endValue = endValue - target.color; Color to = new Color(0, 0, 0, 0); return DOTween.To(() => to, x => { Color diff = x - to; to = x; target.color += diff; }, endValue, duration) .Blendable().SetTarget(target); } #endregion #region Image /// Tweens a Image's color to the given value, /// in a way that allows other DOBlendableColor tweens to work together on the same target, /// instead than fight each other as multiple DOColor would do. /// Also stores the Image as the tween's target so it can be used for filtered operations /// The value to tween toThe duration of the tween public static Tweener DOBlendableColor(this Image target, Color endValue, float duration) { endValue = endValue - target.color; Color to = new Color(0, 0, 0, 0); return DOTween.To(() => to, x => { Color diff = x - to; to = x; target.color += diff; }, endValue, duration) .Blendable().SetTarget(target); } #endregion #region Text /// Tweens a Text's color BY the given value, /// in a way that allows other DOBlendableColor tweens to work together on the same target, /// instead than fight each other as multiple DOColor would do. /// Also stores the Text as the tween's target so it can be used for filtered operations /// The value to tween toThe duration of the tween public static Tweener DOBlendableColor(this Text target, Color endValue, float duration) { endValue = endValue - target.color; Color to = new Color(0, 0, 0, 0); return DOTween.To(() => to, x => { Color diff = x - to; to = x; target.color += diff; }, endValue, duration) .Blendable().SetTarget(target); } #endregion #endregion #endregion // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ // ███ INTERNAL CLASSES ████████████████████████████████████████████████████████████████████████████████████████████████ // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ public static class Utils { /// /// Converts the anchoredPosition of the first RectTransform to the second RectTransform, /// taking into consideration offset, anchors and pivot, and returns the new anchoredPosition /// public static Vector2 SwitchToRectTransform(RectTransform from, RectTransform to) { Vector2 localPoint; Vector2 fromPivotDerivedOffset = new Vector2(from.rect.width * 0.5f + from.rect.xMin, from.rect.height * 0.5f + from.rect.yMin); Vector2 screenP = RectTransformUtility.WorldToScreenPoint(null, from.position); screenP += fromPivotDerivedOffset; RectTransformUtility.ScreenPointToLocalPointInRectangle(to, screenP, null, out localPoint); Vector2 pivotDerivedOffset = new Vector2(to.rect.width * 0.5f + to.rect.xMin, to.rect.height * 0.5f + to.rect.yMin); return to.anchoredPosition + localPoint - pivotDerivedOffset; } } } } #endif