在 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);
    }