Thanks Chaps, both very helpful suggestions.
Robertbu - I still haven’t quite got my around exactly how the dot function works - I just need to meditate on it for a while longer, but I do see how the results can translate into what I’m after - returning a custom enum will be the way forward for me.
Gfoot - I appreciate the alternative. My current project requires the precision of robertbu’s solution and is based on equal weightings between each direction but it’s a good call on being able to adjust the thresholds to apply bias’.
For what it’s worth, I came up with another alternative myself. It’s no more effective that robertbu’s solution but I thought I’d mention it for the benefit of any future readers.
The idea is that you define a point infront, behind, above, below, to the left and to the right of the point of origin directly along each axis. It does matter how far they are from the point of origin, as long as they are all the same distance.
Then, you just check the distance between point at the end of the vector you’re testing and each of the six points previously defined.
The general direction can be defined from which ever of those six points is closest to the point at the end of you vector.
Something like this …
public enum GeneralDirection {
None,
Forwards,
Back,
Left,
Right,
Up,
Down
}
public GeneralDirection GetDirection (Vector3 pointOfOrigin, Vector3 vectorToTest) {
GeneralDirection result = GeneralDirection.None;
float shortestDistance = Mathf.Infinity;
float distance = 0;
Vector3 vectorPosition = pointOfOrigin + vectorToTest;
distance = Mathf.Abs (((pointOfOrigin + Vector3.forward) - vectorToTest).magnitude);
if (distance < shortestDistance)
{
shortestDistance = distance;
result = GeneralDirection.Forwards;
}
distance = Mathf.Abs (((pointOfOrigin -Vector3.forward) - vectorToTest).magnitude);
if (distance < shortestDistance)
{
shortestDistance = distance;
result = GeneralDirection.Back;
}
distance = Mathf.Abs (((pointOfOrigin + Vector3.up) - vectorToTest).magnitude);
if (distance < shortestDistance)
{
shortestDistance = distance;
result = GeneralDirection.Up;
}
distance = Mathf.Abs (((pointOfOrigin + -Vector3.up) - vectorToTest).magnitude);
if (distance < shortestDistance)
{
shortestDistance = distance;
result = GeneralDirection.Down;
}
distance = Mathf.Abs (((pointOfOrigin + Vector3.left) - vectorToTest).magnitude);
if (distance < shortestDistance)
{
shortestDistance = distance;
result = GeneralDirection.Left;
}
distance = Mathf.Abs (((pointOfOrigin + Vector3.right) - vectorToTest).magnitude);
if (distance < shortestDistance)
{
shortestDistance = distance;
result = GeneralDirection.Right;
}
return result;
}
}
It’s not quite as elegant as robertbu’s solution but I reckon it gives the same degree of accuracy but uses ‘Simpler Maths’ - not that that’s a tangible benefit I suppose
It does, however, combine what I think are the strengths of both robertbu’s and gfoot’s solutions in that it should be just as precise as robertbu’s but also you could easily apply a bias to any particular direction by defining the point in front/behind/etc closer or further away from the point of origin - e.g. defining the point above the point of origin closer would apply bias toward it and moving it further away would do the opposite.
This solution would also work whether you normalize the vector or not.
Anyway, as I said, just a thought that may be a better for someone else’s needs.
Thanks again Gents.