I'm looking to find the Euler angle difference (on one axis) between a targets position relative to the players orientation and position.
Hopefully the below image will help illustrate what I want.
What I have attempted so far is this
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);
This will output the angle between 0-180, no matter if its on the left and right.
What I want is the euler angle, so the angle should be represented between 0 to 360 degrees.
I have tried converting the angles to Quaternions but I'm getting inconsistent results. The number goes from very low to high with a small amount of movement in the console
var testRotation = Quaternion.FromToRotation(player.transform.forward,target.transform.position - player.transform.position);
Debug.Log(testRotation.eulerAngles.y);
I have tried doing this using vector3 and dot
Vector3 targetDir = player.transform.position - target.transform.position;
var rot = Mathf.Cos(Vector3.Dot(player.transform.forward, targetDir.normalized));
Debug.Log(rot);
but this will output a number between 0.5 and 0.999
Using Draco18s answer I ended up creating this method (which is far from perfect). It worked for me.
/// <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;
}
Thanks
I'm sure there's a dupe-target somewhere, but I can't find it.
I can, however, find some code that I got from...somewhere a number of years ago, complete with comments.
This will give you a value from -180 to +180. Converting that to 0-360 will require a little math, but should be straight forward (hint: -179.99 -> +180.01).