最终来回晃动物体,缓和吗? [英] Shake an object back and forth with easing at the end?
问题描述
我几乎想要一个震撼的动画,这样它就可以快速来回摇动一秒钟,然后放慢速度,回到原来的位置.继续摇晃有很多答案,但是我如何减少摇晃呢?我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即可,并在一段时间的while循环中执行YourObjTransform.position = defaultPos + UnityEngine.Random.insideUnitSphere * shakeAmount;
.摇动GameObject后,将值重置回其默认位置.
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.
下面的函数是上述语句的完整示例.它需要三个参数:要摇动的GameObject,要摇动GameObject的时间以及何时开始减少摇动.
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
摇晃总计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屋!