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 japtar10101 · Nov 01, 2014 at 04:31 AM · angleraycamerasorigin

Get the angle of a ray in respect to a camera

So here's a challenging question. I have a Ray generated by two points. Assuming the Ray's direction is not the same as camera's forward or backwards direction, how do I get the angle of that ray in respect to a camera?

Here's a few screenshots demonstrating what I'm trying to do.

Button rotated correctly Button rotated incorrectly

I'm attempting to use a two camera setup (one perspective, one orthogonal) to generate a GUI with rotating buttons. The buttons are supposed to point in the direction a transform is at in respect to the character. I've tried the following method of "converting" a point in the ray from the perspective camera ( gameCamera ) to orthogonal camera ( guiCamera ), but the results were inconsistent:

 Vector3 ConvertPoint(Vector3 gamePoint, Camera gameCamera, Camera guiCamera, float distanceFromGuiCamera)
 {
     Vector3 viewPortPoint = gameCamera.WorldToViewportPoint(gamePoint);
     Ray guiRay = guiCamera.ViewportPointToRay(viewPortPoint);
     return guiRay.GetPoint(distanceFromGuiCamera);
 }
 
 static float Angle(Vector3 originPoint, Vector3 endPoint)
 {
     float returnAngle = Mathf.Atan2((endPoint.y - originPoint.y), (endPoint.x - originPoint.x)) * (180f / Mathf.PI);
     while(returnAngle > 0f)
     {
         returnAngle -= 360f;
     }
     while(returnAngle < 0f)
     {
         returnAngle += 360f;
     }
     return returnAngle;
 }
 
 public void PositionButton(Camera gameCamera, Camera guiCamera, Ray characterToTransform, float distanceFromGuiCamera,
     float nearestDistance, float farthestDistance, float lerpValue, float deltaTime)
 {
     // Generate 2 points: one at the origin, and one several units away from it
     origin = ConvertPoint(characterToTransform.origin, gameCamera, guiCamera, distanceFromGuiCamera);
     farthestPoint = characterToTransform.GetPoint(farthestDistance);
     farthestPoint = ConvertPoint(farthestPoint, gameCamera, guiCamera, distanceFromGuiCamera);
     
     float angle = Angle(origin, farthestPoint);
     Quaternion rotation = Quaternion.Euler(0, 0, angle);
     CachedTransform.rotation = rotation;
 }

In particular, Vector3 viewPortPoint = gameCamera.WorldToViewportPoint(gamePoint); has been oddly inaccurate. I don't know if it has to do with how the gameCamera is parented to another object for animation, but one odd scenario includes a camera looking in the positive X direction, while the ray is looking in the positive Z-direction (the screenshots above demonstrates this specific scenario). I would normally expect farthestPoint to be set left of origin, but instead, I get a farthestPoint in the right.

Comment
Add comment · Show 5
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 robertbu · Nov 01, 2014 at 04:36 AM 0
Share

I'm having trouble sorting through the specifics of your question to get to a real answer, but here is a function that finds a signed angle between two Vectors:

 float SignedAngle(Vector3 v1, Vector3 v2, Vector3 normal) {
     Vector3 perp = Vector3.Cross(normal, v1);
     float angle = Vector3.Angle(v1, v2);
     angle *= $$anonymous$$athf.Sign(Vector3.Dot(perp, v2));
     return angle;
 }

avatar image japtar10101 · Nov 01, 2014 at 04:40 AM 0
Share

Interesting, @robertbu. I'll give that a shot tomorrow.

avatar image japtar10101 · Nov 01, 2014 at 05:12 PM 0
Share

I've attempted the following code, but don't get the desired goal:

 static float SignedAngle(Vector3 v1, Vector3 v2, Vector3 normal)
 {
     Vector3 perpendicular = Vector3.Cross(normal, v1);
     float angle = Vector3.Angle(v1, v2);
     angle *= $$anonymous$$athf.Sign(Vector3.Dot(perpendicular, v2));
     //angle += 90f;
     return angle;
 }
 
 public void PositionButton(Camera gameCamera, Camera guiCamera, Ray characterToTransform, float distanceFromGuiCamera,
                            float nearestDistance, float farthestDistance, float lerpValue, float deltaTime)
 {
     // Generate 2 points: one at the character's origin, and one several units away from it
     origin = ConvertPoint(characterToTransform.origin, gameCamera, guiCamera, distanceFromGuiCamera);
     farthestPoint = characterToTransform.GetPoint(farthestDistance);
     float angle = SignedAngle(characterToTransform.origin, farthestPoint, gameCamera.transform.forward * -1);
     Quaternion rotation = Quaternion.Euler(0, 0, angle);

     // Position the buttons
     CachedTransform.position = origin;
     CachedTransform.rotation = rotation;
 }

Now every button gets rotated to the right side of the screen.

avatar image AlwaysSunny · Nov 01, 2014 at 05:24 PM 0
Share

Didn't exa$$anonymous$$e your code in detail, but it sounds like you're trying to convert world-space vectors into screen-space, in which case the angle relative to the camera is non-essential data.

Have a look at transform.InverseTransformDirection() and Camera.WorldToScreenPoint()

avatar image robertbu · Nov 01, 2014 at 06:59 PM 0
Share

Reading your question and code for the third time and trying to fit it into the code you've written is making my head hurt. The problem is that I'm having trouble visualizing what the right solution looks like (and if it is the one you are asking for). Given just the text of the problem you specify:

I have a Ray generated by two points. Assu$$anonymous$$g the Ray's direction is not the same as camera's forward or backwards direction, how do I get the angle of that ray in respect to a camera?

There are a number of solutions, but the most common would be to take the two world points (the origin of the ray, and another point some distance from the origin) and use Camera.WorldToScreenPoint() or Camera.WorldToViewportPoint() to generate two points. Then to get direction:

 Vector3 dir = point2 - point1;
 angle = $$anonymous$$athf.Atan2(dir.y, dir.x) * $$anonymous$$athf.Rad2Deg;
 CachedTransform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);

This code assumes your GUI camera has a rotation of 0,0,0, and that you are using a Sprite or Quad to display the indicator. The indicator needs to point to the right when the rotation is (0,0,0).

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by japtar10101 · Nov 01, 2014 at 07:06 PM

Well this is embarrassing. It looks like the the functions I wrote above is working just fine!

The Ray I was generating was not. I figured it out after putting in a ton of debugging statements. Apologize.

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Raycast Ray ray origin problem 3 Answers

Ray.origin point moving from stationary object? 1 Answer

A little confused about scripting Raycasts 1 Answer

Changing position of a RayCast 1 Answer

Angles from Directions 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