最后在缓和的情况下来回摇动一个物体?

我几乎想要一个刺耳的动画,这样它会快速地来回摇晃一秒钟,然后放慢速度,慢慢回到正常位置。 只有持续震动有很多答案,但我怎么能减少震动呢? 我会Lerp真的很快,还是使用PingPong的function会变慢?

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

至于减少震动,你做shakeAmount += Time.deltaTime; 在while循环中。 这将降低while循环中的摇动速度。

以下function是上述声明的完整示例。 它需要三个参数,GameObject可以摇动,动摇GameObject的时间以及开始减少震动的时间。

例如,如果你将myGameOBject5f3f传递给该函数,它将摇动myGameOBject ,总时间为5秒。 在摇动myGameOBject并且计数器达到3 ,它将开始降低摇动的速度( shakeAmount ),直到计时器达到5

如果要抖动的SpriteRenderSpriteRender ,则将true传递给最后一个参数,以便z轴不会移动,并且在摇动时它只会在Z轴上旋转。

 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); } 

查看具有阻尼效果的cos / sin函数。

  A*Pow(e, -bt/2)*cos(f*t)