如何从一个物体位置到另一个物体位置获得欧拉角度差异

时间:2017-09-05 16:10:48

标签: c# math unity3d vector euler-angles

我希望找到目标位置相对于球员方向和位置之间的欧拉角度差异(在一个轴上)。

希望下面的图片有助于说明我想要的内容。

Euler Angle

到目前为止我的尝试是

    public GameObject player;
    public GameObject target;

    Vector3 targetDir = target.transform.position - player.transform.position;
    float angle = Vector3.Angle(player.transform.forward, targetDir);
    Debug.Log(angle);

这将输出0-180之间的角度,无论它是左侧还是右侧。

我想要的是欧拉角,所以角度应该在0到360度之间。

我尝试将角度转换为Quaternions,但结果不一致。这个数字从非常低到高,在控制台中有少量移动

var testRotation = Quaternion.FromToRotation(player.transform.forward,target.transform.position - player.transform.position);
Debug.Log(testRotation.eulerAngles.y);

我尝试过使用vector3和dot

  Vector3 targetDir = player.transform.position - target.transform.position;
    var rot = Mathf.Cos(Vector3.Dot(player.transform.forward, targetDir.normalized));
    Debug.Log(rot);

但这将输出介于0.5和0.999之间的数字

使用Draco18s的答案我最终创造了这种方法(这远非完美)。它对我有用。

/// <summary>
/// Calculate angle difference on the Y axis between one object (target) and anothers (player) orientation and position as an angle between 0 & 360 degrees
/// </summary>
/// <param name="_target"></param>
/// <param name="_player"></param>
/// <returns></returns>
private float CalcAngle(GameObject _target, GameObject _player)
{
    //Calculate the direction of the target removing any up or down rotation
    Vector3 _newDirection = (new Vector3(_target.transform.position.x, 0, _target.transform.position.z) - new Vector3(_player.transform.position.x, 0, _player.transform.position.z));

    // the vector that we want to measure an angle from
    Vector3 referenceForward = _player.transform.forward;/* some vector that is not Vector3.up */
    // Remove any up or down rotation
    referenceForward = new Vector3(referenceForward.x, 0, referenceForward.z);

    // the vector perpendicular to referenceForward (90 degrees clockwise)
    // (used to determine if angle is positive or negative)
    Vector3 referenceRight = _player.transform.right;
    referenceRight = new Vector3(referenceRight.x, 0, referenceRight.z);

    // Get the angle in degrees between 0 and 180
    float angle = Vector3.Angle(_newDirection, referenceForward);

    // Determine if the degree value should be negative. Here, a positive value
    // from the dot product means that our vector is on the right of the reference vector
    // whereas a negative value means we're on the left.
    float sign = Mathf.Sign(Vector3.Dot(_newDirection, referenceRight));

    // Create an angle between 0-360
    float result = sign * angle;
    if (result < 0)
    {
        result = 360 - Mathf.Abs(result);
    }
    //Give back the result
    return result;
}

谢谢

1 个答案:

答案 0 :(得分:2)

我确定在某个地方有一个欺骗目标,但我找不到它。

但是,我可以找到一些代码,这些代码是我在几年前的某个地方找到的,并附有评论。

private float CalcAngle(Vector3 newDirection) {
    // the vector that we want to measure an angle from
    Vector3 referenceForward = transform.forward;/* some vector that is not Vector3.up */

    // the vector perpendicular to referenceForward (90 degrees clockwise)
    // (used to determine if angle is positive or negative)
    Vector3 referenceRight = transform.right;

    // Get the angle in degrees between 0 and 180
    float angle = Vector3.Angle(newDirection, referenceForward);

    // Determine if the degree value should be negative. Here, a positive value
    // from the dot product means that our vector is on the right of the reference vector
    // whereas a negative value means we're on the left.
    float sign = Mathf.Sign(Vector3.Dot(newDirection, referenceRight));

    return sign * angle;
}

这将为您提供-180到+180之间的值。将其转换为0-360需要一些数学,但应该是直接的(提示:-179.99 - &gt; +180.01)。