- Home /
Find angle to target (not angle to rotate by)
I am trying to find the angle to a target. However, all the solutions I am finding in the Unity community are to find the angle for rotating towards a target. I.e. http://answers.unity3d.com/questions/64509/get-a-gui-2d-arrow-to-turn-to-a-specific-position.html http://forum.unity3d.com/threads/30639-Finding-the-angle-between-a-direction-and-a-point In the above solutions if you start turning towards the target the angle will decrease, where the player and target are stationary in position.
A 2d arrow is what I am after, as exampled in the GUI2d arrow above. I want my angle to be a true angle of the target position in relation to the player. I.e. if the target is above the player then the angle would be 0, to the right then 90, below then 180 or the left then 270 of where the player is facing. Rotation should not matter, only position.
I would appreciate any help.
Answer by WillTAtl · Nov 29, 2011 at 02:07 PM
exact same problem as this question about the angle of a mouse cursor. In that case the math I gave used the standard mathematical angles, 0 being right and increasing counter-clockwise, but it can be switched to up as 0 and increasing clockwise by just swapping x and y when you call Atan2.
Hey, thanks for the quick reply. The problem isn't exactly the same as the mouse cursor post, I have failed to explain it properly. Say that the target was above you, then you rotate so it would effectively (from your point of view) be below you. I would need to recalculate the angle so that the pointer would stay pointed toward the target.
You're still not explaining it very well. I'm completely lost here.
Unless I'm missing something, it is exactly the same problem. The player's rotation is completely ignored, you just use the player's position as the example's "relative to" point and the enemy's position in place of the mouse cursor position.
Only need two changes from the code there...
First line changes from this...
var v:Vector2 = mousePos - relativeToPoint;
to this
var v:Vector2 = enemyPosition - playerPosition;
and then as I explained originally, to get it giving 0=up, 90=right ins$$anonymous$$d of 0=right, 90=up, change the next line, which calls ATan2, from this...
var angleRadians=$$anonymous$$athf.Atan2(v.y, v.x);
to this
var angleRadians=$$anonymous$$athf.Atan2(v.x, v.y); //x and y reversed
I have uploaded a video to youTube of what I am trying to achieve: http://www.youtube.com/watch?v=XNymFhQXeA8
Will, your code will give me the angle to the target based on position only. I need it to also take in account of the player's rotation (see example video above). The player will use the indicator to easily find the target if offscreen.
oh! for some reason I was imagining an overhead shooter.
I'm still slightly confused as to why the example from the other question you originally linked isn't working for you, though. Just to be clear, the black ship in the video is the enemy, and the game is a first-person, cockpit-view thing? That's how it appeared from the video, and the example from the other question should work fine...? What do you mean that the "angle will decrease" when you turn towards the target?
Answer by centaurianmudpig · Dec 04, 2011 at 09:52 PM
I was able to get a rotable GUI texture using the code in the below URL's: http://answers.unity3d.com/questions/11022/how-to-rotate-gui-textures.html http://answers.unity3d.com/questions/64509/get-a-gui-2d-arrow-to-turn-to-a-specific-position.html
It seems to work pretty well.
myOffscreenIndicator is a game object with contains the RotatableGUIItem script.
//Get the targets position on screen into a Vector3
Vector3 targetPos = Camera.current.WorldToScreenPoint (target.transform.position);
//Get the middle of the screen into a Vector3
Vector3 screenMiddle = new Vector3(Screen.width/2, Screen.height/2, 0);
//Compute the angle from screenMiddle to targetPos
float tarAngle = (Mathf.Atan2(targetPos.x-screenMiddle.x,Screen.height-targetPos.y-screenMiddle.y) * Mathf.Rad2Deg)+90;
if (tarAngle < 0) tarAngle +=360;
if(targetPos.z < 0) {
myOffscreenIndicator.GetComponent<RotatableGuiItem>().angle = -(tarAngle-90); //Quaternion.Euler(tarAngle,270,90);
borderPos.x = (Screen.width/2) - Mathf.Cos((tarAngle+180) * Mathf.Deg2Rad) * 100.0f;
borderPos.y = (Screen.height/2) + Mathf.Sin((tarAngle+180) * Mathf.Deg2Rad) * 100.0f;
}
else {
myOffscreenIndicator.GetComponent<RotatableGuiItem>().angle = -(tarAngle+90); //Quaternion.Euler(-tarAngle,90,270);
borderPos.x = (Screen.width/2) - Mathf.Cos((tarAngle) * Mathf.Deg2Rad) * 100.0f;
borderPos.y = (Screen.height/2) + Mathf.Sin((tarAngle) * Mathf.Deg2Rad) * 100.0f;
}
myOffscreenIndicator.transform.position = borderPos;
Your answer
Follow this Question
Related Questions
Snapping to Object Forward Axis 0 Answers
How to move camera on an angle 1 Answer
Else Statement Not Working 1 Answer
How to use the lerp function with rotation? (C#) 1 Answer
GUI box fit in all screens 2 Answers