【问题标题】:Rotate an object smoothly to a value [duplicate]将对象平滑旋转到一个值[重复]
【发布时间】:2022-01-14 12:15:18
【问题描述】:

我有一个可以在 z 轴和 y 轴上旋转的飞机控制器。当上/下或左/右输入 == 0 时,我希望平面旋转重置(再次变为水平)。

经过一些试验和错误,这可行:

if (Input.GetAxis("Horizontal") == 0.0f && transform.rotation.z != 0f) {
  Vector3 tempRotation = new Vector3();
  tempRotation.z = 0.0f;
  transform.rotation = Quaternion.Euler(tempRotation);
}

但是,它会立即卡入到位。我希望它是一个渐进的轮换。这也会对相机产生负面影响(也包括快照)。

我为每个更新周期等尝试了tempRotation.z -= 0.1f; 之类的东西,但是当它变为 0 时这并没有停止(我不知道为什么):

if (Input.GetAxis("Horizontal") == 0.0f && transform.rotation.z != 0.0f) {
  Vector3 tempRotation = transform.rotation.eulerAngles;
  tempRotation.z = (float) Math.Round(tempRot.z, 1);
  tempRotation.z += 0.1f;
  transform.rotation = Quaternion.Euler(tempRotation);
}

有人知道吗?谢谢。

【问题讨论】:

    标签: c# unity3d rotation


    【解决方案1】:

    首先,不要使用transform.rotation.z,除非你对四元数了如指掌。您可能打算使用transform.eulerAngles.z

    可以查看local right的y分量判断是否倾斜,使用Quaternion.LookRotation查找“重置”旋转,这比使用eulerAngles安全一点。

    然后,您必须进行旋转。对于一个非常简单的恒定速度,您可以使用Quaternion.RotateTowards 向它旋转:

    [SerializeField] float resetSpeed;
    
    // ...
    
    if (Input.GetAxis("Horizontal") == 0.0f && !Mathf.Approximately(transform.right.y, 0f))
    {
        Quaternion startRot = transform.rotation;
        Quaternion goalRot = Quaternion.LookRotation(transform.forward);
        transform.rotation = Quaternion.RotateTowards(startRot, goalRot, 
                resetSpeed * Time.deltaTime);
    }
    
    if (Input.GetAxis("Vertical") == 0.0f && !Mathf.Approximately(transform.forward.y, 0f))
    {
        Quaternion startRot = transform.rotation;
        Quaternion goalRot = Quaternion.LookRotation(Vector3.Scale(transform.forward,
                Vector3(1f,0f,1f)), transform.up);
        transform.rotation = Quaternion.RotateTowards(startRot, goalRot, 
                resetSpeed * Time.deltaTime);
    }
    

    【讨论】:

    • 这是完美的@Ruzihm,非常感谢!
    • 我现在正试图让它也适用于上/下旋转,知道为什么这不起作用吗?结合起来,我可以在LookRotation 中添加transform.uptransform.forward 吗? cs if (Input.GetAxis("Vertical") == 0.0f && !Mathf.Approximately(transform.up.z, 0f)) { Quaternion startRot = transform.rotation; Quaternion goalRot = Quaternion.LookRotation(transform.up); transform.rotation = Quaternion.RotateTowards(startRot, goalRot, resetSpeed * Time.deltaTime); }
    • 我会在单独的if 中为"Vertical" 做同样的事情。只有goalRot = Quaternion.LookRotation(Vector3.Scale(new Vector3(1f,0f,1f), transform.forward), transform.up);,你可以检查!Mathf.Approximately(transform.forward.y, 0f)
    • 太棒了,非常感谢。看 Unity 文档时我有点困惑——它指的是颜色,它们根据是指场景还是对象而有所不同。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    • 1970-01-01
    相关资源
    最近更新 更多