所以这个问题可能还不清楚,但是船可以用箭头键完美地旋转,但是当释放箭头键时,我希望它旋转回到位置(0,yRotation,0),但要平滑运动(用户首先旋转的动作相同),知道我该怎么做吗?
xRotation,yRotation和zRotation都初始化为0。
float xThrow = CrossPlatformInputManager.GetAxis("Horizontal");
if(xThrow > 0) {
transform.rotation = Quaternion.Euler(xRotation, yRotation + 0.6f, zRotation - 0.6f);
yRotation += 0.6f;
zRotation -= 0.6f;
}
else if (xThrow < 0)
{
transform.rotation = Quaternion.Euler(xRotation, yRotation - 0.6f, zRotation + 0.6f);
yRotation -= 0.6f;
zRotation += 0.6f;
}
else {
transform.rotation = Quaternion.Euler(0f, yRotation, zRotation);
while (zRotation > 0) {
zRotation -= 0.6f;
}
while (zRotation < 0) {
zRotation += 0.6f;
}
}
我编写的代码将其带回到所需的旋转位置,但是它一点都不平滑,只能作为一个框架来执行。我想实现这一目标,但是要以非常平滑的运动,而不是单个框架。
答案 0 :(得分:0)
假设您想重置else
块中的旋转,则应使用Coroutine。注意,因为我也猜想您正在Update
方法中使用此方法,所以请小心不要启动多个例程。
// set this in the Inspector
public float resetDuration;
// make sure there is only one routine running at once
private bool isResetting;
// ...
else
{
// if no routine is running so far start one
if(!isResetting) StartCoroutine(RotateToIdentity());
}
// ...
private IEnumerator RotateToIdentity()
{
isResetting = true;
// I recommend using this for rotations and not do them by manipulating
// 3 float values. Otherwise could also Lerp all three float values and use them for the rotation here as well
var currentRot = transform.localRotation;
var targetRot = Quaternion.Identity;
// than use those
// var currentX = xRotation;
// var currentY = yRotation;
// var currentZ = zRotation;
var timePassed = 0.0f;
while(timePassed <= resetDuration)
{
// interpolate between the original rotation and the target
// using timePassed / resetDuration as factor => a value between 0 and 1
transform.rotation = Quaternion.Lerp(currentRot, targetRot, timePassed / resetDuration);
// or with your rotations
// xRotation = Mathf.Lerp(currentX, 0, timePassed / resetDuration);
// yRotation = Mathf.Lerp(currentY, 0, timePassed / resetDuration);
// zRotation = Mathf.Lerp(currentZ, 0, timePassed / resetDuration);
// transform.rotation = Quaternion.Euler(xRotation, yRotation, zRotation);
// add passed time since last frame
timePassed += Time.deltaTtime;
// return to the mein thread, render the frame and go on in the next frame
yield return null;
}
// finally apply the target rotation just to be sure to avoid over/under shooting
transform.rotation = targetRot;
// if you really want to go on using xRotation, yRotation and zRotation also reset them when done
xRotation = 0;
yRotation = 0;
zRotation = 0;
isResetting = false;
}
您还应该考虑将Time.deltaTime用于所有轮换。
使用3个单独的lerps的优势之一:用户再次互动后,他就可以中断重置例程
if(xThrow > 0)
{
StopAllCoroutines();
isResetting = false;
// ...
}
else if (xThrow < 0)
{
StopAllCoroutines();
isResetting = false;
// ...
}
// ---