最后在缓和的情况下来回摇动一个物体?
我几乎想要一个刺耳的动画,这样它会快速地来回摇晃一秒钟,然后放慢速度,慢慢回到正常位置。 只有持续震动有很多答案,但我怎么能减少震动呢? 我会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的时间以及开始减少震动的时间。
例如,如果你将myGameOBject
, 5f
, 3f
传递给该函数,它将摇动myGameOBject
,总时间为5
秒。 在摇动myGameOBject
并且计数器达到3
,它将开始降低摇动的速度( shakeAmount
),直到计时器达到5
。
如果要抖动的SpriteRender
是SpriteRender
,则将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)