在 Unity 中旋转对象以在持续时间内面向一个方向?
Rotate object to face a direction in a duration in Unity?
因此,在我的场景中,我有我的主要游戏对象和作为参考的第二个游戏对象。我希望主游戏对象旋转,以便它面向与第二个游戏对象相同的方向。并且这种轮换需要在设定的时间内发生。我们假设持续时间为 3 秒。如果第二个游戏对象的世界旋转为 0, 90, 0,则主游戏对象开始旋转,三秒后它的旋转为 0, 90, 0。
所以,我有了主要游戏对象和第二个游戏对象的变换,现在我需要计算每帧的旋转量,以便在正确的持续时间内进行旋转。
如果有人能帮助我,我将不胜感激!提前谢谢你。
每当您想要在指定时间内移动某物时,我建议您不要在 Update
中执行此操作,而应使用 Coroutine。
它的工作方式类似于一个临时的 Update
方法,每帧执行一次,直到下一帧 yield
。这比 Update
方法更易于维护和控制。
然后根据您的需要使用Quaternion.Lerp
or also Quaternion.Slerp
进行轮换
private IEnumerator RotateOverTime(Transform transformToRotate, Quaternion targetRotation, float duration)
{
var startRotation = transformToRotate.rotation;
var timePassed = 0f;
while(timePassed < duration)
{
var factor = timePassed / duration;
// optional add ease-in and -out
//factor = Mathf.SmoothStep(0, 1, factor);
transformToRotate.rotation = Quaternion.Lerp(startRotation, targetRotation, factor);
// or
//transformToRotate.rotation = Quaternion.Slerp(startRotation, targetRotation, factor);
// increae by the time passed since last frame
timePassed += time.deltaTime;
// important! This tells Unity to interrupt here, render this frame
// and continue from here in the next frame
yield return null;
}
// to be sure to end with exact values set the target rotation fix when done
transformToRotate.rotation = targetRotation;
}
现在,为了开始这个例程,您可以通过 StartCoroutine
调用它,例如
// simply stop any other running routine so you don't get concurrent ones
StopAllCoroutines();
StartCoroutine(transformToRotate, otherTransform.rotation, 3f);
您可以使用 Slerp 方法。所以,更新中应该是这样的:
transform.rotation = Quaternion.Slerp(transform.rotation, secondTransform.rotation, rotationSpeed * Time.deltaTime);
https://answers.unity.com/questions/765197/how-do-i-rotate-an-object-over-a-set-time.html
简答:
float totalRotationTime = 5.0f;
float y_degreesPerSecond = go.transform.eulerAngles.y / totalRotationTime;
float x_degs = go.transform.x/ totalRotationTime;
//etc...
go.transform.Rotate(new Vector3(x_degs * Time.deltaTime, degreesPerSecond * Time.deltaTime, 0));
我已经更新了derHugo给出的答案,通过这个更新你可以定义对象在给定时间内旋转的时间和角度。
private IEnumerator RotateOverTime(float duration)
{
var timePassed = 0f;
while (timePassed < duration)
{
var factor = timePassed / duration;
factor = (Mathf.PI / 2) * (Time.deltaTime / duration);
print("factor: " + factor);
hedefAraYon = Vector3.RotateTowards(transform.forward, hedefYon, factor, 0.0f);
transform.rotation = Quaternion.LookRotation(hedefAraYon, Vector3.back);
// increae by the time passed since last frame
timePassed += Time.deltaTime;
// important! This tells Unity to interrupt here, render this frame
// and continue from here in the next frame
yield return null;
}
// donme takılı kalabiliyor, o yüzden 0,5f olarak ayarladım
if (Quaternion.Angle(transform.rotation, Quaternion.LookRotation(hedefYon, Vector3.back)) <= 0.5f)
{
Vector3 tempRotation = transform.rotation.eulerAngles;
tempRotation.x = Mathf.RoundToInt(tempRotation.x);
tempRotation.y = Mathf.RoundToInt(tempRotation.y);
tempRotation.z = Mathf.RoundToInt(tempRotation.z);
transform.rotation = Quaternion.Euler(tempRotation);
}
hareketDurumu = HAREKET_DURUMU.DURUYOR;
print("Time Passed-Döner OK: " + timePassedOverall);
}
因此,在我的场景中,我有我的主要游戏对象和作为参考的第二个游戏对象。我希望主游戏对象旋转,以便它面向与第二个游戏对象相同的方向。并且这种轮换需要在设定的时间内发生。我们假设持续时间为 3 秒。如果第二个游戏对象的世界旋转为 0, 90, 0,则主游戏对象开始旋转,三秒后它的旋转为 0, 90, 0。
所以,我有了主要游戏对象和第二个游戏对象的变换,现在我需要计算每帧的旋转量,以便在正确的持续时间内进行旋转。
如果有人能帮助我,我将不胜感激!提前谢谢你。
每当您想要在指定时间内移动某物时,我建议您不要在 Update
中执行此操作,而应使用 Coroutine。
它的工作方式类似于一个临时的 Update
方法,每帧执行一次,直到下一帧 yield
。这比 Update
方法更易于维护和控制。
然后根据您的需要使用Quaternion.Lerp
or also Quaternion.Slerp
进行轮换
private IEnumerator RotateOverTime(Transform transformToRotate, Quaternion targetRotation, float duration)
{
var startRotation = transformToRotate.rotation;
var timePassed = 0f;
while(timePassed < duration)
{
var factor = timePassed / duration;
// optional add ease-in and -out
//factor = Mathf.SmoothStep(0, 1, factor);
transformToRotate.rotation = Quaternion.Lerp(startRotation, targetRotation, factor);
// or
//transformToRotate.rotation = Quaternion.Slerp(startRotation, targetRotation, factor);
// increae by the time passed since last frame
timePassed += time.deltaTime;
// important! This tells Unity to interrupt here, render this frame
// and continue from here in the next frame
yield return null;
}
// to be sure to end with exact values set the target rotation fix when done
transformToRotate.rotation = targetRotation;
}
现在,为了开始这个例程,您可以通过 StartCoroutine
调用它,例如
// simply stop any other running routine so you don't get concurrent ones
StopAllCoroutines();
StartCoroutine(transformToRotate, otherTransform.rotation, 3f);
您可以使用 Slerp 方法。所以,更新中应该是这样的:
transform.rotation = Quaternion.Slerp(transform.rotation, secondTransform.rotation, rotationSpeed * Time.deltaTime);
https://answers.unity.com/questions/765197/how-do-i-rotate-an-object-over-a-set-time.html
简答:
float totalRotationTime = 5.0f;
float y_degreesPerSecond = go.transform.eulerAngles.y / totalRotationTime;
float x_degs = go.transform.x/ totalRotationTime;
//etc...
go.transform.Rotate(new Vector3(x_degs * Time.deltaTime, degreesPerSecond * Time.deltaTime, 0));
我已经更新了derHugo给出的答案,通过这个更新你可以定义对象在给定时间内旋转的时间和角度。
private IEnumerator RotateOverTime(float duration)
{
var timePassed = 0f;
while (timePassed < duration)
{
var factor = timePassed / duration;
factor = (Mathf.PI / 2) * (Time.deltaTime / duration);
print("factor: " + factor);
hedefAraYon = Vector3.RotateTowards(transform.forward, hedefYon, factor, 0.0f);
transform.rotation = Quaternion.LookRotation(hedefAraYon, Vector3.back);
// increae by the time passed since last frame
timePassed += Time.deltaTime;
// important! This tells Unity to interrupt here, render this frame
// and continue from here in the next frame
yield return null;
}
// donme takılı kalabiliyor, o yüzden 0,5f olarak ayarladım
if (Quaternion.Angle(transform.rotation, Quaternion.LookRotation(hedefYon, Vector3.back)) <= 0.5f)
{
Vector3 tempRotation = transform.rotation.eulerAngles;
tempRotation.x = Mathf.RoundToInt(tempRotation.x);
tempRotation.y = Mathf.RoundToInt(tempRotation.y);
tempRotation.z = Mathf.RoundToInt(tempRotation.z);
transform.rotation = Quaternion.Euler(tempRotation);
}
hareketDurumu = HAREKET_DURUMU.DURUYOR;
print("Time Passed-Döner OK: " + timePassedOverall);
}