首页 > 解决方案 > 如何在统一中获得像东西方这样的实际方向?

问题描述

我正在使用谷歌 API 统一显示地图,并从玩家位置生成地图位置上的对象。现在我想知道实际的方向。这意味着从谷歌地图或谷歌API识别方向(东西向)。

我做了一个代码,但它没有给我实际的方向。

 var v = transform.forward;
 v.y = 0;
 v.Normalize();

 if (Vector3.Angle(v, Vector3.forward) <= 45.0) {
     Debug.Log("North");
 }
 else if (Vector3.Angle(v, Vector3.right) <= 45.0) {
     Debug.Log("East");
 }
 else if (Vector3.Angle(v, Vector3.back) <= 45.0) {
     Debug.Log("South");
 }
 else {
     Debug.Log("West");
 }

标签: google-mapsunity3dgoogle-maps-api-3map-directions

解决方案


使用Vector3.forward

写作的速记new Vector3(0, 0, 1)

返回 Unity 本身的前 Z 轴方向。这完全取决于您启动 Unity/您的应用程序时设备的方向,与现实世界坐标无关。


您可能更愿意寻找Compass哪个返回手机的实际方向,例如使用magneticHeading

相对于北极的以度数为单位的航向。

此属性中的值始终是相对于当前方向的屏幕顶部测量的。磁北的航向与真正的地理北不完全相同 - 要获得准确的航向,请使用该trueHeading属性。

public class Example : MonoBehaviour
{
    void Update()
    {
        // Orient an object to point to magnetic north.
        transform.rotation = Quaternion.Euler(0, -Input.compass.magneticHeading, 0);
    }
}

或使用trueHeading

相对于地理北极的以度数为单位的航向。

此属性中的值始终是相对于当前方向的屏幕顶部测量的。请注意,如果您希望此属性包含有效值,您还必须通过调用启用位置更新Input.location.Start()

using UnityEngine;

public class Example : MonoBehaviour
{
    void Start()
    {
        Input.location.Start();
    }

    void Update()
    {
        // Orient an object to point northward.
        transform.rotation = Quaternion.Euler(0, -Input.compass.trueHeading, 0);
    }
}

因此,对于您的用例,您只需使用例如

using UnityEngine;

public enum Heading
{
    North,
    East,
    South,
    West
}

public class Example : MonoBehaviour
{
    [Header("Debug")]
    [SerializeField] [Range(0f, 360f)] private float northHeading;

    [Header("OutputValues")]
    [SerializeField] private float myHeading;
    [SerializeField] private float dif;
    [SerializeField] private Heading heading;

    // Update is called once per frame
    private void Update()
    {
        // only use the Y component of the objects orientation
        // always returns a value between 0 and 360
        myHeading = transform.eulerAngles.y;
        // also this is always a value between 0 and 360
        northHeading = Input.compass.magneticHeading;

        dif = myHeading - northHeading;
        // wrap the value so it is always between 0 and 360
        if (dif < 0) dif += 360f;

        if (dif > 45 && dif <= 135)
        {
            heading = Heading.East;
        }
        else if (dif > 135 && dif <= 225)
        {
            heading = Heading.South;
        }
        else if (dif > 225 && dif <= 315)
        {
            heading = Heading.West;
        }
        else
        {
            heading = Heading.North;
        }
    }

    // Only for debug and demo
    // draw a pointer towards north
    private void OnDrawGizmos()
    {
        var northDirection = (Quaternion.Euler(0, northHeading, 0) * Vector3.forward).normalized;

        Gizmos.color = Color.red;
        Gizmos.DrawLine(transform.position, transform.position + northDirection);

        var objectDirection = (Quaternion.Euler(0, transform.eulerAngles.y, 0) * Vector3.forward).normalized;
        Gizmos.color = Color.blue;
        Gizmos.DrawLine(transform.position, transform.position + objectDirection);
    }
}

在这个小演示中,您可以看到物体前进方向的蓝色指针和北方向的红色矢量。您可以看到Heading枚举值如何根据对象方向变化。

由于我是在 PC 上完成的,因此我必须手动“调整”北向,稍后您将通过手机获得此信息。

在此处输入图像描述


推荐阅读