Given a transform and a target position, you can use the following code to get the “bearing” of your target. The function is also overloaded so you can just provide two GameObjects.
// Takes a starting object and a target object, and returns the angle to the target 0-359°
function GetBearing(startingObject : GameObject, targetObject : GameObject) : float {
// Call the "real" GetBearing, passing it our object's transform, and the target's position
return GetBearing(startingObject.transform, targetObject.transform.position);
}
// Takes a starting object's Transform, and a target object's position, and returns the angle to the target 0-359°
function GetBearing(startingObjectTransform : Transform, targetPosition : Vector3) : float {
// First, create a Vector3 that is "pointing" from our startingObject to our target.
var vectorToTarget : Vector3 = targetPosition - startingObjectTransform.position;
// Now, discover the angle between our forward "heading", and the vector we just created.
// This only gives a result between 0-180, however... we don't know if the target is to our left or right!
var angleToTarget : float = Vector3.Angle(startingObjectTransform.forward, vectorToTarget);
// AngleDir returns exactly 1 if the target is to the "right" of our forward "heading"
var directionResult = AngleDir(startingObjectTransform.forward, vectorToTarget, startingObjectTransform.up);
// Based on directionResult, decide if angleToTarget was an angle on the "left" or "right" side of our object.
if (directionResult == 1) {
return 360 - angleToTarget;
} else {
return angleToTarget;
}
}
// Given a "forward" heading, a target direction, and an "up" direction, decide if the targetDirection is to our left, right, or front/back.
function AngleDir(forwardVector : Vector3, targetDirection : Vector3, upVector : Vector3) : int {
var perpendicular : Vector3 = Vector3.Cross(forwardVector, targetDirection);
var direction : float = Vector3.Dot(perpendicular, upVector);
if (direction > 0.0) {
return 1;
} else if (direction < 0.0) {
return -1;
} else {
return 0;
}
}
Use like so:
var firingShip : GameObject;
var targetShip : Vector3;
var bearing : float;
// bearing will contain the 360° angle to the targetShip
bearing = GetBearing(firingShip.transform, targetShip);
OR like:
var firingShip : GameObject;
var targetShip : GameObject;
var bearing : float;
// bearing will contain the 360° angle to the targetShip
bearing = GetBearing(firingShip, targetShip);
C# Version without comments (Courtesy Chronos-L):
float GetBearing( GameObject startingObject, GameObject targetObject ) {
return GetBearing( startingObject.transform, targetObject.transform.position );
}
float GetBearing( Transform startTransform, Vector3 targetPosition ) {
Vector3 vectorToTarget = targetPosition - startTransform.position;
float angleToTarget = Vector3.Angle( startTransform.forward, vectorToTarget );
int direction = AngleDir( startTransform.forward, vectorToTarget, startTransform.up );
return ( direction == 1 )? 360f-angleToTarget: angleToTarget;
}
int AngleDir( Vector3 forwardVector, Vector3 targetDirection, Vector3 upVector ) {
float direction = Vector3.Dot( Vector3.Cross( forwardVector, targetDirection ), upVector );
if( direction > 0f ) {
return 1;
}
else if( direction < 0f ) {
return -1;
}
else {
return 0;
}
}
This information was gleaned from the following threads: Angle of object relative to transform of second object - Questions & Answers - Unity Discussions http://forum.unity3d.com/threads/52930-Vector3-Angle()?highlight=AngleDir http://forum.unity3d.com/threads/31420-Left-Right-test-function
I was going to self-answer with a working, commented code example. All the other threads on this topic require you to hunt through multiple other threads. Why did you close this?
– TheMaster42mainly because it's answered in that question already ("duplicate question" and all), but go ahead if you've got something :)
– LoiusFair, sorry - I wasn't clear enough what I was planning. I hope this is a useful addition. Thank you. =)
– TheMaster42aw, no prob. us high-falutin' mod types recently got a bit of a bug into our systems, we're all a little trigger-happy on the close button for now, trying to 'straighten up this town', as it were. nice answer, btw. :)
– Loius