Ejemplo n.º 1
0
        public override void SetFrom(TweenerCore <Quaternion, Vector3, QuaternionOptions> t, bool isRelative)
        {
            Vector3 prevEndVal = t.endValue;

            t.endValue = t.getter().eulerAngles;
            if (t.plugOptions.rotateMode == RotateMode.Fast && !t.isRelative)
            {
                t.startValue = prevEndVal;
            }
            else if (t.plugOptions.rotateMode == RotateMode.FastBeyond360)
            {
                t.startValue = t.endValue + prevEndVal;
            }
            else
            {
                Quaternion rot = t.getter();
                if (t.plugOptions.rotateMode == RotateMode.WorldAxisAdd)
                {
                    t.startValue = (rot * Quaternion.Inverse(rot) * Quaternion.Euler(prevEndVal) * rot).eulerAngles;
                }
                else
                {
                    t.startValue = (rot * Quaternion.Euler(prevEndVal)).eulerAngles;
                }
                t.endValue = -prevEndVal;
            }
            t.setter(Quaternion.Euler(t.startValue));
        }
Ejemplo n.º 2
0
        public override void SetFrom(TweenerCore <Vector2, Vector2, VectorOptions> t, Vector2 fromValue, bool setImmediately)
        {
            t.startValue = fromValue;
            if (setImmediately)
            {
                Vector2 to;
                switch (t.plugOptions.axisConstraint)
                {
                case AxisConstraint.X:
                    to   = t.getter();
                    to.x = fromValue.x;
                    break;

                case AxisConstraint.Y:
                    to   = t.getter();
                    to.y = fromValue.y;
                    break;

                default:
                    to = fromValue;
                    break;
                }
                if (t.plugOptions.snapping)
                {
                    to.x = (float)Math.Round(to.x);
                    to.y = (float)Math.Round(to.y);
                }
                t.setter(to);
            }
        }
Ejemplo n.º 3
0
        public override void SetFrom(TweenerCore <Quaternion, Vector3, QuaternionOptions> t, bool isRelative)
        {
            Vector3 endValue = t.endValue;

            t.endValue = t.getter().eulerAngles;
            if (t.plugOptions.rotateMode == RotateMode.Fast && !t.isRelative)
            {
                t.startValue = endValue;
            }
            else if (t.plugOptions.rotateMode == RotateMode.FastBeyond360)
            {
                t.startValue = t.endValue + endValue;
            }
            else
            {
                Quaternion quaternion = t.getter();
                if (t.plugOptions.rotateMode == RotateMode.WorldAxisAdd)
                {
                    t.startValue = (quaternion * Quaternion.Inverse(quaternion) * Quaternion.Euler(endValue) * quaternion).eulerAngles;
                }
                else
                {
                    t.startValue = (quaternion * Quaternion.Euler(endValue)).eulerAngles;
                }
                t.endValue = -endValue;
            }
            t.setter(Quaternion.Euler(t.startValue));
        }
Ejemplo n.º 4
0
        // CALLED VIA Tween the moment the tween starts, AFTER any delay has elapsed
        // (unless it's a FROM tween, in which case it will be called BEFORE any eventual delay).
        // Returns TRUE in case of success,
        // FALSE if there are missing references and the tween needs to be killed
        internal static bool DoStartup <T1, T2, TPlugOptions>(TweenerCore <T1, T2, TPlugOptions> t) where TPlugOptions : struct, IPlugOptions
        {
            t.startupDone = true;

            // Special startup operations
            if (t.specialStartupMode != SpecialStartupMode.None)
            {
                if (!DOStartupSpecials(t))
                {
                    return(false);
                }
            }

            if (!t.hasManuallySetStartValue)
            {
                // Take start value from current target value
                if (DOTween.useSafeMode)
                {
                    try {
                        t.startValue = t.tweenPlugin.ConvertToStartValue(t, t.getter());
                    } catch (Exception e) {
                        if (Debugger.logPriority >= 1)
                        {
                            Debugger.LogWarning(string.Format(
                                                    "Tween startup failed (NULL target/property - {0}): the tween will now be killed ► {1}", e.TargetSite, e.Message
                                                    ));
                        }
                        DOTween.safeModeReport.Add(SafeModeReport.SafeModeReportType.StartupFailure);
                        return(false); // Target/field doesn't exist: kill tween
                    }
                }
                else
                {
                    t.startValue = t.tweenPlugin.ConvertToStartValue(t, t.getter());
                }
            }

            if (t.isRelative)
            {
                t.tweenPlugin.SetRelativeEndValue(t);
            }

            t.tweenPlugin.SetChangeValue(t);

            // Duration based startup operations
            DOStartupDurationBased(t);

            // Applied here so that the eventual duration derived from a speedBased tween has been set
            if (t.duration <= 0)
            {
                t.easeType = Ease.INTERNAL_Zero;
            }

            return(true);
        }
Ejemplo n.º 5
0
        // CALLED BY TweenerCore
        internal static TweenerCore <T1, T2, TPlugOptions> DoChangeEndValue <T1, T2, TPlugOptions>(
            TweenerCore <T1, T2, TPlugOptions> t, T2 newEndValue, float newDuration, bool snapStartValue
            ) where TPlugOptions : struct, IPlugOptions
        {
            t.endValue   = newEndValue;
            t.isRelative = false;

            if (t.startupDone)
            {
                if (t.specialStartupMode != SpecialStartupMode.None)
                {
                    if (!DOStartupSpecials(t))
                    {
                        return(null);
                    }
                }
                if (snapStartValue)
                {
                    // Reassign startValue with current target's value
                    if (DOTween.useSafeMode)
                    {
                        try {
                            t.startValue = t.tweenPlugin.ConvertToStartValue(t, t.getter());
                        } catch {
                            // Target/field doesn't exist: kill tween
                            TweenManager.Despawn(t);
                            DOTween.safeModeReport.Add(SafeModeReport.SafeModeReportType.TargetOrFieldMissing);
                            return(null);
                        }
                    }
                    else
                    {
                        t.startValue = t.tweenPlugin.ConvertToStartValue(t, t.getter());
                    }
                }
                t.tweenPlugin.SetChangeValue(t);
            }

            if (newDuration > 0)
            {
                t.duration = newDuration;
                if (t.startupDone)
                {
                    DOStartupDurationBased(t);
                }
            }

            // Force rewind
            DoGoto(t, 0, 0, UpdateMode.IgnoreOnUpdate);

            return(t);
        }
Ejemplo n.º 6
0
        // CALLED VIA Tween the moment the tween starts, AFTER any delay has elapsed
        // (unless it's a FROM tween, in which case it will be called BEFORE any eventual delay).
        // Returns TRUE in case of success,
        // FALSE if there are missing references and the tween needs to be killed
        internal static bool DoStartup <T1, T2, TPlugOptions>(TweenerCore <T1, T2, TPlugOptions> t) where TPlugOptions : struct
        {
            t.startupDone = true;

            // Special startup operations
            if (t.specialStartupMode != SpecialStartupMode.None)
            {
                if (!DOStartupSpecials(t))
                {
                    return(false);
                }
            }

            if (!t.hasManuallySetStartValue)
            {
                // Take start value from current target value
                if (DOTween.useSafeMode)
                {
                    try {
                        t.startValue = t.tweenPlugin.ConvertToStartValue(t, t.getter());
                    } catch {
                        return(false); // Target/field doesn't exist: kill tween
                    }
                }
                else
                {
                    t.startValue = t.tweenPlugin.ConvertToStartValue(t, t.getter());
                }
            }

            if (t.isRelative)
            {
                t.tweenPlugin.SetRelativeEndValue(t);
            }

            t.tweenPlugin.SetChangeValue(t);

            // Duration based startup operations
            DOStartupDurationBased(t);

            // Applied here so that the eventual duration derived from a speedBased tween has been set
            if (t.duration <= 0)
            {
                t.easeType = Ease.INTERNAL_Zero;
            }

            return(true);
        }
Ejemplo n.º 7
0
        public override void SetFrom(TweenerCore <Vector3, Vector3, VectorOptions> t, bool isRelative)
        {
            Vector3 prevEndVal = t.endValue;

            t.endValue   = t.getter();
            t.startValue = isRelative ? t.endValue + prevEndVal : prevEndVal;
            Vector3 to = t.endValue;

            switch (t.plugOptions.axisConstraint)
            {
            case AxisConstraint.X:
                to.x = t.startValue.x;
                break;

            case AxisConstraint.Y:
                to.y = t.startValue.y;
                break;

            case AxisConstraint.Z:
                to.z = t.startValue.z;
                break;

            default:
                to = t.startValue;
                break;
            }
            if (t.plugOptions.snapping)
            {
                to.x = (float)Math.Round(to.x);
                to.y = (float)Math.Round(to.y);
                to.z = (float)Math.Round(to.z);
            }
            t.setter(to);
        }
Ejemplo n.º 8
0
        // Recreates waypoints with correct control points and eventual additional starting point
        // then sets the final path version
        public override void SetChangeValue(TweenerCore <Vector3, Path, PathOptions> t)
        {
            Transform trans = (Transform)t.target;

            if (t.plugOptions.orientType == OrientType.ToPath && t.plugOptions.useLocalPosition)
            {
                t.plugOptions.parent = trans.parent;
            }

            if (t.endValue.isFinalized)
            {
                t.changeValue = t.endValue;
                return;
            }

            Vector3 currVal = t.getter();
            Path    path = t.endValue;
            int     unmodifiedWpsLen = path.wps.Length;
            int     additionalWps = 0;
            bool    hasAdditionalStartingP = false, hasAdditionalEndingP = false;

            // Create final wps and add eventual starting/ending waypoints
            if (path.wps[0] != currVal)
            {
                hasAdditionalStartingP = true;
                additionalWps         += 1;
            }
            if (t.plugOptions.isClosedPath && path.wps[unmodifiedWpsLen - 1] != currVal)
            {
                hasAdditionalEndingP = true;
                additionalWps       += 1;
            }
            int wpsLen = unmodifiedWpsLen + additionalWps;

            Vector3[] wps    = new Vector3[wpsLen];
            int       indMod = hasAdditionalStartingP ? 1 : 0;

            if (hasAdditionalStartingP)
            {
                wps[0] = currVal;
            }
            for (int i = 0; i < unmodifiedWpsLen; ++i)
            {
                wps[i + indMod] = path.wps[i];
            }
            if (hasAdditionalEndingP)
            {
                wps[wps.Length - 1] = wps[0];
            }
            path.wps = wps;

            // Finalize path
            path.FinalizePath(t.plugOptions.isClosedPath, t.plugOptions.lockPositionAxis, currVal);

            t.plugOptions.startupRot  = trans.rotation;
            t.plugOptions.startupZRot = trans.eulerAngles.z;

            // Set changeValue as a reference to endValue
            t.changeValue = t.endValue;
        }
Ejemplo n.º 9
0
        // Token: 0x060001D2 RID: 466 RVA: 0x0000A5D8 File Offset: 0x000087D8
        public override void SetFrom(TweenerCore <Vector2, Vector2, VectorOptions> t, bool isRelative)
        {
            Vector2 endValue = t.endValue;

            t.endValue   = t.getter();
            t.startValue = (isRelative ? (t.endValue + endValue) : endValue);
            Vector2        vector         = t.endValue;
            AxisConstraint axisConstraint = t.plugOptions.axisConstraint;

            if (axisConstraint != AxisConstraint.X)
            {
                if (axisConstraint != AxisConstraint.Y)
                {
                    vector = t.startValue;
                }
                else
                {
                    vector.y = t.startValue.y;
                }
            }
            else
            {
                vector.x = t.startValue.x;
            }
            if (t.plugOptions.snapping)
            {
                vector.x = (float)Math.Round((double)vector.x);
                vector.y = (float)Math.Round((double)vector.y);
            }
            t.setter(vector);
        }
Ejemplo n.º 10
0
        // Returns TRUE if it's successful, FALSE otherwise
        // Behaves like a regular shake, but also changes the endValues so that they reflect the local axis rotation of the camera
        internal static bool SetCameraShakePosition(TweenerCore <Vector3, Vector3[], Vector3ArrayOptions> t)
        {
            if (!SetShake(t))
            {
                return(false);
            }

            Camera target = t.target as Camera;

            if (target == null)
            {
                return(false);
            }

            Vector3   startupVal = t.getter();
            Transform trans      = target.transform;
            int       len        = t.endValue.Length;

            for (int i = 0; i < len; i++)
            {
                Vector3 endVal = t.endValue[i];
                t.endValue[i] = (trans.localRotation * (endVal - startupVal)) + startupVal;
            }
            return(true);
        }
Ejemplo n.º 11
0
        public override void SetFrom(TweenerCore <Color2, Color2, ColorOptions> t, bool isRelative)
        {
            Color2 prevEndVal = t.endValue;

            t.endValue = t.getter();
            if (isRelative)
            {
                t.startValue = new Color2(t.endValue.ca + prevEndVal.ca, t.endValue.cb + prevEndVal.cb);
            }
            else
            {
                t.startValue = new Color2(prevEndVal.ca, prevEndVal.cb);
            }
            Color2 to = t.endValue;

            if (!t.plugOptions.alphaOnly)
            {
                to = t.startValue;
            }
            else
            {
                to.ca.a = t.startValue.ca.a;
                to.cb.a = t.startValue.cb.a;
            }
            t.setter(to);
        }
Ejemplo n.º 12
0
        public override void SetFrom(TweenerCore <Vector3, Vector3, VectorOptions> t, bool isRelative)
        {
            Vector3 endValue = t.endValue;

            t.endValue   = t.getter();
            t.startValue = (isRelative ? (t.endValue + endValue) : endValue);
            Vector3 vector = t.endValue;

            switch (t.plugOptions.axisConstraint)
            {
            case AxisConstraint.X:
                vector.x = t.startValue.x;
                break;

            case AxisConstraint.Y:
                vector.y = t.startValue.y;
                break;

            case AxisConstraint.Z:
                vector.z = t.startValue.z;
                break;

            default:
                vector = t.startValue;
                break;
            }
            if (t.plugOptions.snapping)
            {
                vector.x = (float)Math.Round((double)vector.x);
                vector.y = (float)Math.Round((double)vector.y);
                vector.z = (float)Math.Round((double)vector.z);
            }
            t.setter(vector);
        }
Ejemplo n.º 13
0
        public override void SetFrom(TweenerCore <Vector2, Vector2, VectorOptions> t, bool isRelative)
        {
            Vector2 endValue = t.endValue;

            t.endValue   = t.getter();
            t.startValue = (isRelative ? (t.endValue + endValue) : endValue);
            Vector2 pNewValue = t.endValue;

            switch (t.plugOptions.axisConstraint)
            {
            case AxisConstraint.X:
                pNewValue.x = t.startValue.x;
                goto IL_88;

            case AxisConstraint.Y:
                pNewValue.y = t.startValue.y;
                goto IL_88;
            }
            pNewValue = t.startValue;
IL_88:
            if (t.plugOptions.snapping)
            {
                pNewValue.x = (float)Math.Round((double)pNewValue.x);
                pNewValue.y = (float)Math.Round((double)pNewValue.y);
            }
            t.setter(pNewValue);
        }
Ejemplo n.º 14
0
        public override void SetFrom(TweenerCore <Color2, Color2, ColorOptions> t, bool isRelative)
        {
            Color2 endValue = t.endValue;

            t.endValue = t.getter();
            if (isRelative)
            {
                t.startValue = new Color2(t.endValue.ca + endValue.ca, t.endValue.cb + endValue.cb);
            }
            else
            {
                t.startValue = new Color2(endValue.ca, endValue.cb);
            }
            Color2 pNewValue = t.endValue;

            if (!t.plugOptions.alphaOnly)
            {
                pNewValue = t.startValue;
            }
            else
            {
                pNewValue.ca.a = t.startValue.ca.a;
                pNewValue.cb.a = t.startValue.cb.a;
            }
            t.setter(pNewValue);
        }
Ejemplo n.º 15
0
        public override void SetFrom(TweenerCore <Quaternion, Quaternion, NoOptions> t, bool isRelative)
        {
            Quaternion endValue = t.endValue;

            t.endValue   = t.getter();
            t.startValue = isRelative ? (t.endValue * endValue) : endValue;
            t.setter(t.startValue);
        }
Ejemplo n.º 16
0
        public override void SetFrom(TweenerCore <float, float, FloatOptions> t, bool isRelative)
        {
            float prevEndVal = t.endValue;

            t.endValue   = t.getter();
            t.startValue = isRelative ? t.endValue + prevEndVal : prevEndVal;
            t.setter(!t.plugOptions.snapping ? t.startValue : (float)Math.Round(t.startValue));
        }
Ejemplo n.º 17
0
        public override void SetFrom(TweenerCore <int, int, NoOptions> t, bool isRelative)
        {
            int endValue = t.endValue;

            t.endValue   = t.getter();
            t.startValue = (isRelative ? (t.endValue + endValue) : endValue);
            t.setter(t.startValue);
        }
Ejemplo n.º 18
0
        public override void SetFrom(TweenerCore <ulong, ulong, NoOptions> t, bool isRelative)
        {
            ulong prevEndVal = t.endValue;

            t.endValue   = t.getter();
            t.startValue = isRelative ? t.endValue + prevEndVal : prevEndVal;
            t.setter(t.startValue);
        }
Ejemplo n.º 19
0
        // Token: 0x060001F0 RID: 496 RVA: 0x0000B574 File Offset: 0x00009774
        public override void SetFrom(TweenerCore <float, float, FloatOptions> t, bool isRelative)
        {
            float endValue = t.endValue;

            t.endValue   = t.getter();
            t.startValue = (isRelative ? (t.endValue + endValue) : endValue);
            t.setter((!t.plugOptions.snapping) ? t.startValue : ((float)Math.Round((double)t.startValue)));
        }
Ejemplo n.º 20
0
        public override void SetFrom(TweenerCore <string, string, StringOptions> t, bool isRelative)
        {
            string endValue = t.endValue;

            t.endValue   = t.getter();
            t.startValue = endValue;
            t.setter(t.startValue);
        }
Ejemplo n.º 21
0
    // Sets the values in case of a From tween
    public override void SetFrom(TweenerCore <CustomRange, CustomRange, NoOptions> t, bool isRelative)
    {
        CustomRange prevEndVal = t.endValue;

        t.endValue   = t.getter();
        t.startValue = isRelative ? t.endValue + prevEndVal : prevEndVal;
        t.setter(t.startValue);
    }
Ejemplo n.º 22
0
        public override void SetFrom(TweenerCore <Quaternion, Vector3, QuaternionOptions> t, bool isRelative)
        {
            Vector3 prevEndVal = t.endValue;

            t.endValue   = t.getter().eulerAngles;
            t.startValue = isRelative ? t.endValue + prevEndVal : prevEndVal;
            t.setter(Quaternion.Euler(t.startValue));
        }
Ejemplo n.º 23
0
    public override void SetFrom(TweenerCore <Angle, Angle, AngleOptions> t, bool isRelative)
    {
        //開始値と終了値を反転させる
        Angle prevEndAngle = t.endValue;

        t.endValue   = t.getter();
        t.startValue = isRelative ? t.endValue + prevEndAngle : prevEndAngle;
        t.setter(t.startValue);
    }
Ejemplo n.º 24
0
        public override void SetFrom(TweenerCore <VertexGradient, VertexGradient, NoOptions> t, bool isRelative)
        {
            var prevEndVal = t.endValue;

            t.endValue   = t.getter();
            t.startValue = isRelative ? Add(t.endValue, prevEndVal) : prevEndVal;
            t.startValue = prevEndVal;
            t.setter(t.startValue);
        }
Ejemplo n.º 25
0
        public override void SetFrom(TweenerCore <Vector3, Vector3, TweenPlugVector3LookAtOptions> t, bool isRelative)
        {
            Vector3 prevEndVal = t.endValue;

            t.endValue   = t.getter();
            t.startValue = isRelative ? t.endValue + prevEndVal : prevEndVal;
            Vector3 to = t.startValue;

            t.setter(to);
        }
Ejemplo n.º 26
0
        public override void SetRelativeEndValue(TweenerCore <Vector3, Path, PathOptions> t)
        {
            Vector3 startP = t.getter();
            int     count  = t.endValue.wps.Length;

            for (int i = 0; i < count; ++i)
            {
                t.endValue.wps[i] += startP;
            }
        }
Ejemplo n.º 27
0
        internal static Tweener DoChangeEndValue <T1, T2, TPlugOptions>(TweenerCore <T1, T2, TPlugOptions> t, T2 newEndValue, float newDuration, bool snapStartValue) where TPlugOptions : struct
        {
            t.endValue   = newEndValue;
            t.isRelative = false;
            if (!t.startupDone)
            {
                goto Label_0086;
            }
            if ((t.specialStartupMode != SpecialStartupMode.None) && !DOStartupSpecials <T1, T2, TPlugOptions>(t))
            {
                return(null);
            }
            if (snapStartValue)
            {
                if (DOTween.useSafeMode)
                {
                    try
                    {
                        t.startValue = t.tweenPlugin.ConvertToStartValue(t, t.getter());
                        goto Label_007A;
                    }
                    catch
                    {
                        TweenManager.Despawn(t, true);
                        return(null);
                    }
                }
                t.startValue = t.tweenPlugin.ConvertToStartValue(t, t.getter());
            }
Label_007A:
            t.tweenPlugin.SetChangeValue(t);
Label_0086:
            if (newDuration > 0f)
            {
                t.duration = newDuration;
                if (t.startupDone)
                {
                    DOStartupDurationBased <T1, T2, TPlugOptions>(t);
                }
            }
            Tween.DoGoto(t, 0f, 0, UpdateMode.IgnoreOnUpdate);
            return(t);
        }
Ejemplo n.º 28
0
 public override void SetRelativeEndValue(TweenerCore <Vector3, Path, PathOptions> t)
 {
     if (!t.endValue.isFinalized)
     {
         Vector3 b   = t.getter();
         int     num = t.endValue.wps.Length;
         for (int i = 0; i < num; i++)
         {
             ref Vector3 val = ref t.endValue.wps[i];
             val += b;
         }
     }
Ejemplo n.º 29
0
        public override void SetChangeValue(TweenerCore <Vector3, Path, PathOptions> t)
        {
            Transform transform = (Transform)t.target;

            if (t.plugOptions.orientType == OrientType.ToPath && t.plugOptions.useLocalPosition)
            {
                t.plugOptions.parent = transform.parent;
            }
            if (t.endValue.isFinalized)
            {
                t.changeValue = t.endValue;
                return;
            }
            Vector3 vector   = t.getter();
            Path    endValue = t.endValue;
            int     num      = endValue.wps.Length;
            int     num2     = 0;
            bool    flag     = false;
            bool    flag2    = false;

            if (endValue.wps[0] != vector)
            {
                flag = true;
                num2++;
            }
            if (t.plugOptions.isClosedPath && endValue.wps[num - 1] != vector)
            {
                flag2 = true;
                num2++;
            }
            int num3 = num + num2;

            Vector3[] array = new Vector3[num3];
            int       num4  = flag ? 1 : 0;

            if (flag)
            {
                array[0] = vector;
            }
            for (int i = 0; i < num; i++)
            {
                array[i + num4] = endValue.wps[i];
            }
            if (flag2)
            {
                array[array.Length - 1] = array[0];
            }
            endValue.wps = array;
            endValue.FinalizePath(t.plugOptions.isClosedPath, t.plugOptions.lockPositionAxis, vector);
            t.plugOptions.startupRot  = transform.rotation;
            t.plugOptions.startupZRot = transform.eulerAngles.z;
            t.changeValue             = t.endValue;
        }
Ejemplo n.º 30
0
 public override void SetFrom(TweenerCore <Color, Color, ColorOptions> t, Color fromValue, bool setImmediately)
 {
     t.startValue = fromValue;
     if (setImmediately)
     {
         Color to = fromValue;
         if (t.plugOptions.alphaOnly)
         {
             to   = t.getter();
             to.a = fromValue.a;
         }
         t.setter(to);
     }
 }
Ejemplo n.º 31
0
        // Returns TRUE if it's successful, FALSE otherwise
        // Behaves like a regular shake, but also changes the endValues so that they reflect the local axis rotation of the camera
        internal static bool SetCameraShakePosition(TweenerCore<Vector3, Vector3[], Vector3ArrayOptions> t)
        {
            if (!SetShake(t)) return false;

            Camera target = t.target as Camera;
            if (target == null) return false;

            Vector3 startupVal = t.getter();
            Transform trans = target.transform;
            int len = t.endValue.Length;
            for (int i = 0; i < len; i++) {
                Vector3 endVal = t.endValue[i];
                t.endValue[i] = (trans.localRotation * (endVal - startupVal)) + startupVal;
            }
            return true;
        }
Ejemplo n.º 32
0
        // Returns TRUE if it's successful, FALSE otherwise
        internal static bool SetPunch(TweenerCore<Vector3, Vector3[], Vector3ArrayOptions> t)
        {
            Vector3 startupVal;
            try {
                startupVal = t.getter();
            } catch { return false; }

            // Force specific settings
            t.isRelative = t.isSpeedBased = false;
            t.easeType = Ease.OutQuad;
            t.customEase = null;

            int len = t.endValue.Length;
            for (int i = 0; i < len; i++) t.endValue[i] = t.endValue[i] + startupVal;
            return true;
        }