如何在Unity中获得像东西这样的实际方向?

huangapple go评论95阅读模式
英文:

How to get an actual direction like east - west in unity?

问题

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

> 我编写了以下代码,但它不会给我实际的方向。

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

if (Vector3.Angle(v, Vector3.forward) <= 45.0) {
    Debug.Log("北");
}
else if (Vector3.Angle(v, Vector3.right) <= 45.0) {
    Debug.Log("东");
}
else if (Vector3.Angle(v, Vector3.back) <= 45.0) {
    Debug.Log("南");
}
else {
    Debug.Log("西");
}
英文:

I am using google API to show a map in unity and also generate object on map's location from player position. Now I want to know actual direction. It means identify direction (east-west) from google maps or google API.

> I made a code but it doesn't give me actual direction.

 var v = transform.forward;
 v.y = 0;
 v.Normalize();
 
 if (Vector3.Angle(v, Vector3.forward) &lt;= 45.0) {
     Debug.Log(&quot;North&quot;);
 }
 else if (Vector3.Angle(v, Vector3.right) &lt;= 45.0) {
     Debug.Log(&quot;East&quot;);
 }
 else if (Vector3.Angle(v, Vector3.back) &lt;= 45.0) {
     Debug.Log(&quot;South&quot;);
 }
 else {
     Debug.Log(&quot;West&quot;);
 }

答案1

得分: 3

// language-all: lang-c#

using `Vector3.forward`

> 缩写表示`new Vector3(0, 0, 1)`的写法。

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

---

您可能更想要的是[`Compass`](https://docs.unity3d.com/ScriptReference/Compass.html),它返回您手机的实际方向,例如使用[`magneticHeading`](https://docs.unity3d.com/ScriptReference/Compass-magneticHeading.html)

> 相对于**磁性**北极的角度。
>
> 此属性中的值始终相对于屏幕顶部在其当前方向上进行测量。磁性北极的方向与真正的地理北极不完全相同 - 要获得精确的方向,请使用[`trueHeading`](https://docs.unity3d.com/ScriptReference/Compass-trueHeading.html)属性。
>
> ```csharp
> public class Example : MonoBehaviour
> {
>     void Update()
>     {
>         // 将对象定向到磁性北方。
>         transform.rotation = Quaternion.Euler(0, -Input.compass.magneticHeading, 0);
>     }
> }
> ```

或者使用[`trueHeading`](https://docs.unity3d.com/ScriptReference/Compass-trueHeading.html)

> 相对于**地理**北极的角度。
>
> 此属性中的值始终相对于屏幕顶部在其当前方向上进行测量。请注意,如果您想使此属性包含有效值,必须通过调用`Input.location.Start()`启用位置更新。
>
> ```csharp
> using UnityEngine;
> 
> public class Example : MonoBehaviour
> {
>     void Start()
>     {
>         Input.location.Start();
>     }
> 
>     void Update()
>     {
>         // 将对象定向北方。
>         transform.rotation = Quaternion.Euler(0, -Input.compass.trueHeading, 0);
>     }
> }
> ```

---

因此,对于您的用例,您可以简单地使用:

```csharp
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
    private void Update()
    {
        // 仅使用对象方向的Y分量
        // 始终返回0到360之间的值
        myHeading = transform.eulerAngles.y;
        // 这也始终是0到360之间的值
        northHeading = Input.compass.magneticHeading;

        dif = myHeading - northHeading;
        // 将值包装在0到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;
        }
    }

    // 仅用于调试和演示
    // 画一个指向北方的指针
    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上执行此操作,我必须手动“调整”北方方向,稍后您将从您的手机获得此信息。


<details>
<summary>英文:</summary>
&lt;!-- language-all: lang-c# --&gt;
using `Vector3.forward`
&gt; Shorthand for writing `new Vector3(0, 0, 1)`.
returns you the forward Z axis direction of Unity itself. This depends entirely on the orientation of your device when you started Unity/your app and has nothing to do with real world coordinates. 
---
You are probably rather looking for [`Compass`](https://docs.unity3d.com/ScriptReference/Compass.html) which returns the actual orientation of your phone e.g. using [`magneticHeading`](https://docs.unity3d.com/ScriptReference/Compass-magneticHeading.html) 
&gt; The heading in degrees relative to the **magnetic** North Pole.
&gt; 
&gt; The value in this property is always measured relative to the top of
&gt; the screen in its current orientation. The heading of magnetic north
&gt; is not exactly the same as true geographical north - to get the exact
&gt; heading, use the [`trueHeading`](https://docs.unity3d.com/ScriptReference/Compass-trueHeading.html) property.
&gt; 
&gt;     public class Example : MonoBehaviour
&gt;     {
&gt;         void Update()
&gt;         {
&gt;             // Orient an object to point to magnetic north.
&gt;             transform.rotation = Quaternion.Euler(0, -Input.compass.magneticHeading, 0);
&gt;         }
&gt;     }
or using the [`trueHeading`](https://docs.unity3d.com/ScriptReference/Compass-trueHeading.html)
&gt; The heading in degrees relative to the **geographic** North Pole.
&gt; 
&gt; The value in this property is always measured relative to the top of
&gt; the screen in its current orientation. Note, that if you want this
&gt; property to contain a valid value, you must also enable location
&gt; updates by calling `Input.location.Start()`.
&gt; 
&gt;     using UnityEngine;
&gt; 
&gt;     public class Example : MonoBehaviour
&gt;     {
&gt;         void Start()
&gt;         {
&gt;             Input.location.Start();
&gt;         }
&gt;
&gt;         void Update()
&gt;         {
&gt;             // Orient an object to point northward.
&gt;             transform.rotation = Quaternion.Euler(0, -Input.compass.trueHeading, 0);
&gt;         }
&gt;     }
---
So for your use case you would simply use e.g.
using UnityEngine;
public enum Heading
{
North,
East,
South,
West
}
public class Example : MonoBehaviour
{
[Header(&quot;Debug&quot;)]
[SerializeField] [Range(0f, 360f)] private float northHeading;
[Header(&quot;OutputValues&quot;)]
[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 &lt; 0) dif += 360f;
if (dif &gt; 45 &amp;&amp; dif &lt;= 135)
{
heading = Heading.East;
}
else if (dif &gt; 135 &amp;&amp; dif &lt;= 225)
{
heading = Heading.South;
}
else if (dif &gt; 225 &amp;&amp; dif &lt;= 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);
}
}
---
In the little demo you can see the blue pointer for the object&#39;s forward direction and the red vector for the north direction. You can see how the `Heading` enum value changes according to the objects orientation.
*Since I did it on a PC I had to manually &quot;adjust&quot; a north direction, later you will get this from your phone.*
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/kAKXh.gif
</details>

huangapple
  • 本文由 发表于 2020年1月6日 20:07:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/59611833.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定