using Vector3.forward
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
which returns the actual orientation of your phone e.g. using magneticHeading
The heading in degrees relative to the magnetic North Pole.
The value in this property is always measured relative to the top of
the screen in its current orientation. The heading of magnetic north
is not exactly the same as true geographical north - to get the exact
heading, use the trueHeading
property.
public class Example : MonoBehaviour
{
void Update()
{
// Orient an object to point to magnetic north.
transform.rotation = Quaternion.Euler(0, -Input.compass.magneticHeading, 0);
}
}
or using the trueHeading
The heading in degrees relative to the geographic North Pole.
The value in this property is always measured relative to the top of
the screen in its current orientation. Note, that if you want this
property to contain a valid value, you must also enable location
updates by calling 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);
}
}
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("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);
}
}
In the little demo you can see the blue pointer for the object'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 "adjust" a north direction, later you will get this from your phone.
