【问题标题】:Can you set max angles for RotateAround in Unity?你可以在 Unity 中为 RotateAround 设置最大角度吗?
【发布时间】:2016-05-07 06:26:22
【问题描述】:

这并没有实现我真正想要的。它基本上只是围绕一个空旋转,直到达到最大值。当我使用此代码时,它运行良好。 “最大”角度会根据您决定首先移动的方式而变化。有没有办法设置最大旋转角度?

 using UnityEngine;
using System.Collections;

public class CameraMovement : MonoBehaviour {
    Transform rotAround;
    public float maxRotation = 0;
    // Use this for initialization
    void Start () {
        rotAround = GameObject.Find ("CamRotation").GetComponent <Transform> ();
    }

    // Update is called once per frame
    void Update () {
        if (Input.GetKey (KeyCode.D) && maxRotation < 52.0f) {
            transform.RotateAround (rotAround.position, Vector3.down, 100 * Time.deltaTime);
            maxRotation += 1;
        }
        if (Input.GetKey (KeyCode.A) && maxRotation > -52.0f) {
            transform.RotateAround (rotAround.position, Vector3.up, 100 * Time.deltaTime);
            maxRotation -= 1;
        }
    }
}

【问题讨论】:

  • 100 * Time.deltaTime 不等于 1,这是一个错误的假设。事实上,你永远无法判断 Time.deltaTime 下一帧是什么,但它大约是 1 / 60,所以 0.016667。
  • @MikeSmith 你永远不应该指望Time.deltaTime 保持不变。这只是当前帧和最后一帧之间经过的时间量。这对于调节不规则帧速率的计算非常有用。
  • @yes 嗯,抱歉,我没有。我以为是帧速率时间,可能会有所不同。我使用了 100,因为在我最初的 50 时,相机移动太慢了。除非你是在评论别人。
  • @MikeSmith 但是你为什么只在旋转中添加 1。 100 / 60 大约是 1.66667 而不是 1。也是的,Time.deltaTime 是 2 帧之间的时间,它会有所不同。但请参阅 gjttt1s 的答案,我确定它有效......
  • @是的,我实际上并没有在任何类型的旋转中添加 1。它更像是我的假边界,因为我不知道如何设置最大旋转角度。游戏开始时,凸轮处于默认位置,而无意义的变量 maxRotation 为 0。它基本上所做的就是每次移动时加 1。当它运行 Update() 循环时,它会检查 maxRotation 变量是否仍在它的“边界”内,如果是,您可以在该帧上移动。但是,例如,如果您大于 90 或小于 -90,则 if 语句将是错误的,您无法再朝那个方向移动。

标签: c# unity3d rotation euler-angles


【解决方案1】:

您将每帧添加 1 到 maxRotation。您需要添加Time.deltaTime,否则您的maxRotation 将根据您的帧速率在不同时间到达。只需更改此设置即可使您的游戏对象以相同的角度停止,无论它们以何种方式转动。

这是一种快速简单的方法。另一个是做一些数学。找到rotateAround transform.position 和相机开始transform.position 之差的arctan(使用Mathf.Atan2),然后从相机当前transform.position 减去rotateAround 位置将得到当前角度(下面的例子)。然后,您可以使用此值来检查旋转是否应该继续。有关Atan2 工作原理的更多信息,请参阅this answer

请注意,Mathf.Atan2 返回传递给它的向量与 X 轴之间的角度(以弧度为单位)(您可能不希望这样)。我认为find the angle between three vectors(我认为你确实想要)你将不得不考虑他们各自的 arctans 的差异(我没有检查过这个,它是为了简洁起见的伪代码)。像这样:

float angle = 
Atan2(cameraStartPos.y - rotatePointPos.y, cameraStartPos.x - rotatePointPos.x) -
Atan2(cameraCurrentPos.y - rotatePointPos.y, cameraStartPos.x - rotatePointPos.x);

比这更好,让团结为你做这一切!使用Vector3.Angle

float angle = Vector3.Angle(rotateAround.position - cameraStart.position,  
                            rotateAround.position - cameraEnd.position));

您的最终代码可能类似于:

public class CameraMovement : MonoBehaviour {

    Transform rotAround;
    private Vector3 startPosition;
    public float maxRotation = 0; // set this to the maximum angle in degrees

    void Start () 
    {
        rotAround = GameObject.Find ("CamRotation").GetComponent <Transform> ();
        startPosition = transform.position;
    }


    void Update () 
    {

        float currentAngle = Vector3.Angle(rotAround.position - startPosition,
                                           rotAround.position - transform.position));

        if (Input.GetKey (KeyCode.D) && maxRotation < currentAngle) 
        {
            transform.RotateAround (rotAround.position, Vector3.down, 100 * Time.deltaTime);
        }

        if (Input.GetKey (KeyCode.A) && maxRotation < currentAngle) 
        {
            transform.RotateAround (rotAround.position, Vector3.up, 100 * Time.deltaTime);
        }
    }
}

请注意,从Vector3.Angle 返回的角度在达到 180 度时会“翻转”,因此您可以将最大角度设置为 180 以下的任何值,并且它将停在两侧的同一点。

【讨论】:

    【解决方案2】:

    为什么不使用 Random.Range(min,max) 作为最大和最小范围,然后在旋转中指定该角度。

    【讨论】:

    • 尽管上面的代码目前可能显示出看似随机的行为,但 OP 并没有要求随机边界,那么 random 将如何提供帮助?
    猜你喜欢
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    • 2012-12-02
    相关资源
    最近更新 更多