【问题标题】:Smoothly Rotate Object Towards Target Object向目标对象平滑旋转对象
【发布时间】:2019-09-06 00:46:31
【问题描述】:

我想将我的玩家载具旋转到目标对象的方向/侧面。 通过以下图片,我试图以更好的方式解释我的观点:

我想将下面的坦克对象旋转到另一个坦克对象,以便它可以指向那个方向。

我为此目的编写了这段代码,但它不起作用:

IEnumerator DoRotationAtTargetDirection(Transform opponentPlayer)
{
    Quaternion targetRotation = Quaternion.identity;
    do
    {
        Debug.Log("do rotation");
        Vector3 targetDirection = opponentPlayer.position - transform.position;
        targetRotation = Quaternion.LookRotation(targetDirection);
        Quaternion nextRotation = Quaternion.Lerp(transform.localRotation, targetRotation, Time.deltaTime);
        transform.localRotation = nextRotation;
        yield return null;

    } while (Quaternion.Angle(transform.localRotation, targetRotation) < 0.01f);
}

我只想平稳地旋转并停在目标物体上。 请分享您对此的建议。

编辑:

这是更新后的代码,仍然无法正常工作,坦克对象卡在旋转中,如上图所示:

 IEnumerator DoRotationAtTargetDirection(Transform opponentPlayer)
{
    Quaternion targetRotation = Quaternion.identity;
    do
    {
        Debug.Log("do rotation");

        Vector3 targetDirection = (opponentPlayer.position - transform.position).normalized;
        targetRotation = Quaternion.LookRotation(targetDirection);
        transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, Time.deltaTime);

        yield return null;

    } while (Quaternion.Angle(transform.rotation, targetRotation) < 0.01f);
}

坦克物体前进方向:

【问题讨论】:

  • 而不是完全旋转到目标对象 - 它就像我上面的图像一样停止。
  • 感谢您的修改,这已成为一个非常高质量的问题!

标签: c# unity3d


【解决方案1】:

Time.deltaTime 是不合适的 lerp 参数。相反,定义一个float rotationSpeed 并使用rotationSpeed * Time.deltaTime 作为maxDegreesDelta 的参数Quaternion.RotateTowards

此外,以这种方式使用LookRotation 将为您提供世界空间旋转。所以你应该把你的结果分配给transform.rotation而不是transform.localRotation

总的来说,这些变化可能如下所示:

public float rotationSpeed;

IEnumerator DoRotationAtTargetDirection(Transform opponentPlayer)
{
    Quaternion targetRotation = Quaternion.identity;
    do
    {
        Debug.Log("do rotation");
        Vector3 targetDirection = opponentPlayer.position - transform.position;
        targetRotation = Quaternion.LookRotation(targetDirection);
        Quaternion nextRotation = Quaternion.RotateTowards(
                transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
        transform.rotation = nextRotation;
        yield return null;

    } while (Quaternion.Angle(transform.rotation, targetRotation) > 0.01f);
}

【讨论】:

  • 检查我更新的代码仍然无法正常工作,并且我已将 localRotation 更改为正常旋转 - 如果我们与 Time.deltaTime 相乘也无所谓,因为我有完整的枚举器仅用于此目的,尽管它需要更长的时间
  • 仅使用Time.deltaTime 与使用rotationSpeed = 1f 相同,所以这很好:) 我会继续研究为什么问题仍未解决
  • 哦,伙计,你是天才 :) 非常感谢...... - 从上面删除本地旋转它可能不起作用,虽然我没有测试过。
  • 1. RotateTowards 永远不会超过目标。如果您将LerpTime.deltaTime 一起使用,并且设备由于某种原因滞后,因此您的框架具有非常大的Time.deltaTime &gt; 1,那么它会输出一个结果,它可能会旋转到它应该去的地方。如果Time.deltaTime &gt; 2 那么它会比以前更远离目标。理论上你可以使用Lerp(a,b,Mathf.Min(1f,Time.deltaTime));
  • @Siddharth 当您有基于增量的连续累积操作时,始终使用..Towards 方法是一种很好的做法。 Mathf 包含 intfloat 等基本数据类型。在Vector2Vector3 以及Quaternion 中也有版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-07
  • 1970-01-01
  • 2015-11-12
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
相关资源
最近更新 更多