最后用缓动来回摇晃对象? [英] Shake an object back and forth with easing at the end?

查看:23
本文介绍了最后用缓动来回摇晃对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我几乎想要一个不和谐的动画,让它快速来回摇晃一秒钟,然后放慢速度,慢慢回到正常位置.有很多关于继续摇晃的答案,但我该如何减少摇晃呢?我会 Lerp 真的很快,还是使用 PingPong 和一个减慢的函数?

I almost want a jarring animation, such that it shakes back and forth rapidly for a second, and then slows back down, easing back into its normal position. There are tons of answers for just continues shaking, but how would I decrease the shake? Would I Lerp really fast, or use PingPong with a function that slows?

推荐答案

您可以通过获取原始位置然后在协程函数中简单地摇动 GameObject,执行 YourObjTransform.position = defaultPos + UnityEngine.Random.insideUnitSphere *shakeAmount; 在一段时间内循环.摇动游戏对象后,将值重置回其默认位置.

You simply can simply shake a GameObject with by getting the original position then in a coroutine function, do YourObjTransform.position = defaultPos + UnityEngine.Random.insideUnitSphere * shakeAmount; in a while loop for a certain time. After shaking the GameObject, reset the value back to its default position.

至于减少抖动,您在while循环中执行shakeAmount += Time.deltaTime;.这将降低 while 循环中的抖动速度.

As for decreasing the shake, you do shakeAmount += Time.deltaTime; in the while loop. This will decrease the shake speed in the while loop.

下面的函数是上述语句的完整示例.它需要三个参数,要晃动的游戏对象、晃动游戏对象的时间以及开始减少晃动的时间.

The function below is a complete example of the above statement. It takes three parameters, the GameObject to shake, how long to shake the GameObject and what time to start decreasing the shake.

例如,如果你将myGameOBject5f3f传入函数,它会震动myGameOBjectcode> 的总时间为 5 秒.当摇动myGameOBject,计数器达到3时,它会开始降低摇动的速度(shakeAmount),直到定时器达到5.

For example,if you pass in myGameOBject, 5f, 3f to the function, it will shake the myGameOBject for a total time of 5 seconds. While shaking the myGameOBject and the counter reaches 3, it will start to decrease the speed(shakeAmount) of the shake until timer reaches 5.

如果要摇晃的GameObject是SpriteRender,则将true传递给最后一个参数,这样z轴不会移动,摇晃时它只会在Z轴旋转.

Pass true to the last parameter if the GameObject to shake is a SpriteRender so that the z axis won't move and it will only rotate in Z axis when shaking.

public GameObject GameObjectToShake;
bool shaking = false;

IEnumerator shakeGameObjectCOR(GameObject objectToShake, float totalShakeDuration, float decreasePoint, bool objectIs2D = false)
{
    if (decreasePoint >= totalShakeDuration)
    {
        Debug.LogError("decreasePoint must be less than totalShakeDuration...Exiting");
        yield break; //Exit!
    }

    //Get Original Pos and rot
    Transform objTransform = objectToShake.transform;
    Vector3 defaultPos = objTransform.position;
    Quaternion defaultRot = objTransform.rotation;

    float counter = 0f;

    //Shake Speed
    const float speed = 0.1f;

    //Angle Rotation(Optional)
    const float angleRot = 4;

    //Do the actual shaking
    while (counter < totalShakeDuration)
    {
        counter += Time.deltaTime;
        float decreaseSpeed = speed;
        float decreaseAngle = angleRot;

        //Shake GameObject
        if (objectIs2D)
        {
            //Don't Translate the Z Axis if 2D Object
            Vector3 tempPos = defaultPos + UnityEngine.Random.insideUnitSphere * decreaseSpeed;
            tempPos.z = defaultPos.z;
            objTransform.position = tempPos;

            //Only Rotate the Z axis if 2D
            objTransform.rotation = defaultRot * Quaternion.AngleAxis(UnityEngine.Random.Range(-angleRot, angleRot), new Vector3(0f, 0f, 1f));
        }
        else
        {
            objTransform.position = defaultPos + UnityEngine.Random.insideUnitSphere * decreaseSpeed;
            objTransform.rotation = defaultRot * Quaternion.AngleAxis(UnityEngine.Random.Range(-angleRot, angleRot), new Vector3(1f, 1f, 1f));
        }
        yield return null;


        //Check if we have reached the decreasePoint then start decreasing  decreaseSpeed value
        if (counter >= decreasePoint)
        {
            Debug.Log("Decreasing shake");

            //Reset counter to 0 
            counter = 0f;
            while (counter <= decreasePoint)
            {
                counter += Time.deltaTime;
                decreaseSpeed = Mathf.Lerp(speed, 0, counter / decreasePoint);
                decreaseAngle = Mathf.Lerp(angleRot, 0, counter / decreasePoint);

                Debug.Log("Decrease Value: " + decreaseSpeed);

                //Shake GameObject
                if (objectIs2D)
                {
                    //Don't Translate the Z Axis if 2D Object
                    Vector3 tempPos = defaultPos + UnityEngine.Random.insideUnitSphere * decreaseSpeed;
                    tempPos.z = defaultPos.z;
                    objTransform.position = tempPos;

                    //Only Rotate the Z axis if 2D
                    objTransform.rotation = defaultRot * Quaternion.AngleAxis(UnityEngine.Random.Range(-decreaseAngle, decreaseAngle), new Vector3(0f, 0f, 1f));
                }
                else
                {
                    objTransform.position = defaultPos + UnityEngine.Random.insideUnitSphere * decreaseSpeed;
                    objTransform.rotation = defaultRot * Quaternion.AngleAxis(UnityEngine.Random.Range(-decreaseAngle, decreaseAngle), new Vector3(1f, 1f, 1f));
                }
                yield return null;
            }

            //Break from the outer loop
            break;
        }
    }
    objTransform.position = defaultPos; //Reset to original postion
    objTransform.rotation = defaultRot;//Reset to original rotation

    shaking = false; //So that we can call this function next time
    Debug.Log("Done!");
}


void shakeGameObject(GameObject objectToShake, float shakeDuration, float decreasePoint, bool objectIs2D = false)
{
    if (shaking)
    {
        return;
    }
    shaking = true;
    StartCoroutine(shakeGameObjectCOR(objectToShake, shakeDuration, decreasePoint, objectIs2D));
}

void Start()
{
    shakeGameObject(GameObjectToShake, 5, 3f, false);
}

这篇关于最后用缓动来回摇晃对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆