我正在尝试自动在Unity中对第三人称角色进行随机旋转,并且希望对旋转进行动画,就好像我是使用开箱即用的控制器自己旋转玩家一样和WASD键。目标是随机旋转的NPC,在人群中寻找某人。
这是我到目前为止在更新的协程中尝试过的。
float xDegress = Random.Range(10f, 75f);
float yDegress = Random.Range(10f, 75f);
float zDegress = Random.Range(10f, 75f);
// Works but immediate
this.transform.Rotate(0f, yDegress, 0f);
// Works but immediate
this.transform.LookAt(new Vector3(xDegress, 0f, zDegress));
// Doesn't work
rB.rotation = Quaternion.Lerp(transform.rotation, new Quaternion(0, yDegress, 0, 0), 0.5f);
// Doesn't work
rB.MoveRotation(new Quaternion(0, yDegress, 0, 1).normalized);
// Works but immediate
Vector3 newPosition = new Vector3(xDegress, 0f, zDegress);
transform.rotation = Quaternion.Lerp(
transform.rotation,
Quaternion.LookRotation(newPosition, Vector3.up),
0.5f);
yield return new WaitForSeconds(_pauseSeconds);
这里是NPC的检查员,这是标准资产中的Ethan。
答案 0 :(得分:0)
首先,因为它是RigidBody
,所以您完全不应该使用transform.rotation =
或transform.
,而应该使用rb.MoveRotation
或任何rb.rotation
方法。
比您以错误的方式使用Lerp
。您想要的是一个从0
到1
的值。始终以固定的0.5f
因子调用一次,导致第一和第二个旋转中间
一个-立即。
首先,您需要轮换的持续时间。
// How long in seconds should the rotation take?
// might be a constant or set via the inspector
public float rotationDuration = 1.0f;
比开始旋转之前先旋转和结束旋转
float xDegress = Random.Range(10f, 75f);
float yDegress = Random.Range(10f, 75f);
float zDegress = Random.Range(10f, 75f);
var currentRotation = transform.rotation;
var targetRotation = currentRotation * Quaternion.Euler(xDegress, yDegress, zDegress);
// or
Vector3 newPosition = new Vector3(xDegress, 0f, zDegress);
var targetRotation = Quaternion.LookRotation(newPosition, Vector3.up);
// or whatever your target rotation shall be
现在,由于您已经在协程中,因此只需添加一个while
循环即可在所需的持续时间内执行旋转(不过请不要忘记yield
)
var passedTime = 1.0f;
while(passedTime < rotationDuration)
{
// interpolate the rotation between the original and the targetRotation
// factor is a value between 0 and 1
rb.MoveRotation = Quaternion.Lerp(currentRotation, targetRotation, passedTime / rotationDuration);
// add time passed since last frame
passedtime += Time.deltaTime;
yield return null;
}
// to avoid overshooting set the target rotation fix when done
transform.rotation = targetRotation;
yield return new WaitForSeconds(_pauseSeconds);