Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by TheMaster42 · Apr 09, 2013 at 08:22 AM · positionmathangle

Given starting Transform and target position, how to find full 360° angle to the target?

I have a GameObject, and a target's position (in world coordinates). I want to find the "full" 360° angle to the target (such that "left" gives 90 degrees, "right" gives 270, etc.).

Example: my script is running on a sailing ship, and, given the coordinates of another ship, I want to find the angle to the other ship, starting at my ship's bow and rotating counter-clockwise.

This has been answered piecemeal in other questions, but I wanted to put it all in one place, with a single, fully-functioning code example in the answer.

Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image TheMaster42 · Apr 09, 2013 at 08:39 AM 1
Share

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?

avatar image Loius · Apr 09, 2013 at 08:41 AM 1
Share

mainly because it's answered in that question already ("duplicate question" and all), but go ahead if you've got something :)

avatar image TheMaster42 · Apr 09, 2013 at 08:54 AM 0
Share

Fair, sorry - I wasn't clear enough what I was planning. I hope this is a useful addition. Thank you. =)

avatar image Loius · Apr 09, 2013 at 10:01 AM 0
Share

aw, 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. :)

3 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer Wiki

Answer by TheMaster42 · Apr 09, 2013 at 08:44 AM

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: http://answers.unity3d.com/questions/201996/angle-of-object-relative-to-transform-of-second-ob.html http://forum.unity3d.com/threads/52930-Vector3-Angle()?highlight=AngleDir http://forum.unity3d.com/threads/31420-Left-Right-test-function

Comment
Add comment · Show 11 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Chronos-L · Apr 09, 2013 at 08:47 AM 0
Share

It would great if you write another in C#, just in case there are users that claimed that your code did not work when they write it in C#.

avatar image Chronos-L · Apr 09, 2013 at 08:55 AM 1
Share

One more thing, you should return int ins$$anonymous$$d of float for the AngleDir(). float are not 100% precise, so there are times that if (directionResult == 1) { will not be true even though it should be. If you insist on keeping the float, then use if( $$anonymous$$athf.Approximately( directionResult, 1f ) ) {.

avatar image TheMaster42 · Apr 09, 2013 at 08:55 AM 0
Share

$$anonymous$$y C# is really rusty - I'm sure I'd mess it up. If someone else wrote the code, I'd be happy to include it!

avatar image TheMaster42 · Apr 09, 2013 at 09:01 AM 0
Share

@Chronos-L I was wondering about that! The original example used that... I've fixed it per your suggestion!

avatar image Chronos-L · Apr 09, 2013 at 09:06 AM 1
Share

Another thing, this is urgent:

 //This is incorrect
 var angleToTarget : float = Vector3.Angle(startingObjectTransform.forward, targetPosition);
 
 //Correction
 var angleToTarget : float = Vector3.Angle(startingObjectTransform.forward, vectorToTarget);
Show more comments
avatar image
1

Answer by Chronos-L · Apr 09, 2013 at 09:09 AM

C# Version without comment

 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;
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Sartoris · Oct 24, 2020 at 09:56 AM

@TheMaster42 Hi, thank you for sharing this code. I'm currently trying to use it in a 2D project to get the bearing between the player's submarine and a ship, but I'm not sure how to adapt it to the 2D environment. Is it enough to replace startTransform.forward with startTransform.right or does it involve normalized values and other changes?

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

13 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Make something arrive at position in exactly X seconds? 2 Answers

arc object's position using sin 1 Answer

How to get 0-360 bearing in 2D? 3 Answers

How do i make a flowing 90 degree turn? 1 Answer

Calcultate spawn position based on spawn volume's rotation 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges