问题描述
我几乎想要一个不和谐的动画,让它快速来回摇晃一秒钟,然后放慢速度,慢慢回到正常位置.有很多关于继续摇晃的答案,但我该如何减少摇晃呢?我会 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.
例如,如果你将myGameOBject
、5f
、3f
传入函数,它会震动myGameOBject
code> 的总时间为 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);
}
这篇关于最后用缓动来回摇晃对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!