Пример #1
0
        /// <summary>
        /// Shakes the vector several times in a random value, up to amount in magnitude.
        /// </summary>
        /// <param name="amount">The maximum displacement of the rotation, in degrees.</param>
        /// <param name="numShakes"> The number of shakes to perform. </param>
        public static CommandDelegate Shake(Ref <Quaternion> rotation, float amount, int numShakes, double duration)
        {
            CheckArgumentNonNull(rotation);
            if (amount <= 0f || amount > 180f)
            {
                throw new ArgumentOutOfRangeException("amount", "Must be larger than 0.");
            }

            if (numShakes <= 0)
            {
                throw new ArgumentOutOfRangeException("numBounces", "Must be larger than 0.");
            }


            amount = Mathf.Abs(amount);

            double avgDuration = duration / (numShakes + 1);

            CommandDelegate[] list = new CommandDelegate[numShakes + 1];
            return(Cmd.Defer(
                       () =>
            {
                var baseVal = rotation.Value;
                for (int i = 0; i < numShakes; ++i)
                {
                    // Generate an offset within the range -amount, amount
                    var offset = Quaternion.Euler(
                        UnityEngine.Random.Range(-amount, amount),
                        UnityEngine.Random.Range(-amount, amount),
                        UnityEngine.Random.Range(-amount, amount)
                        );

                    float angle = Quaternion.Angle(Quaternion.identity, offset);
                    // Clamp the offset
                    if (angle > amount)
                    {
                        float t = UnityEngine.Random.Range(0f, angle / amount);
                        offset = Quaternion.LerpUnclamped(Quaternion.identity, offset, t);
                    }

                    list[i] = Cmd.RotateTo(rotation, baseVal * offset, avgDuration);
                }

                list[numShakes] = Cmd.RotateTo(rotation, baseVal, avgDuration);
                return Cmd.Sequence(list);
            }
                       ));
        }
Пример #2
0
        public static void TestRotateTo()
        {
            Quaternion       quatStart = Quaternion.Euler(10.0f, 20.0f, 30.0f);
            Quaternion       quatEnd   = Quaternion.Euler(30.0f, 20.0f, 10.0f);
            Quaternion       quatVal   = quatStart;
            Ref <Quaternion> quatRef   = new Ref <Quaternion>(
                () => quatVal,
                t => quatVal = t
                );

            CommandQueue queue = new CommandQueue();

            queue.Enqueue(
                Cmd.Repeat(2,
                           Cmd.RotateTo(quatRef, quatEnd, 1.0)
                           )
                );

            queue.Update(0.5);
            AreEqual(quatVal, Quaternion.Slerp(quatStart, quatEnd, 0.5f), 0.000001f);

            quatVal = Quaternion.identity;
            queue.Update(0.5);
            AreEqual(quatVal, quatEnd, 0.000001f);
            queue.Update(0.5);
            AreEqual(quatVal, quatEnd, 0.000001f);

            // Make sure the rotation ends in the correct position when given a complex easing function.
            queue = new CommandQueue();

            quatVal = quatStart;
            queue.Enqueue(
                Cmd.RotateTo(quatRef, quatEnd, 1f, Ease.OutElastic())
                );

            while (!queue.Update(1 / 30f))
            {
            }

            AreEqual(quatVal, quatEnd, 0.001f);
        }