Shake an object back and forth with easing at the end?

前端 未结 1 1727
逝去的感伤
逝去的感伤 2020-12-19 23:14

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

相关标签:
1条回答
  • 2020-12-19 23:50

    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.

    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.

    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.

    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);
    }
    
    0 讨论(0)
提交回复
热议问题