• 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
1
Question by Reconnoiter · Aug 14, 2017 at 03:34 PM · raycasthitnormalpitch

RaycastHit normal only pitch+yaw

Hi,

I use the normal of RaycastHit to place an gameObject alligned with terrain. The problem I face however is that it wants to use Pitch+Yaw+Roll for the rotation, but I want it to only use Pitch+Yaw (so Roll will be 0), how to get/do this?

-edit, here is a picture to better show what I am trying to do; the green arrow is the direction the object should face on the respective slope: alt text

Comment
Add comment
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

2 Replies

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

Answer by hoekkii · Aug 14, 2017 at 08:54 PM

Short answer:

 public static void Normal2PitchYaw(Vector3 normal, out float pitch, out float yaw)
 {
     yaw = -Mathf.Asin(normal.x) * Mathf.Rad2Deg;
     pitch = Mathf.Atan2(normal.z, normal.y) * Mathf.Rad2Deg;
 }


Long answer:
What do you really want to do?
Because working with pitch, yaw, roll can be a real pain in the.
So I would recommend to use quaternions instead.
If you really need pitch, yaw roll..

Got all the info from this page: https://stackoverflow.com/questions/1568568/how-to-convert-euler-angles-to-directional-vector

You will see on the page; to go from pitch, yaw to a direction vector you'll need this formula:

 x = cos(yaw)*cos(pitch)
 y = sin(yaw)*cos(pitch)
 z = sin(pitch)


To convert this to Unity you can't copy paste it, because in Unity the Y-axis is up. so you will get this:

 x = -sin(yaw) * cos(pitch)
 y = cos(yaw) * cos(pitch)
 z = sin(pitch)


You now can invert the equation to get from direction to pitch and yaw. So you would expect:

 pitch = asin(normal.z)
 yaw = -atan2(normal.x, normal.y)


This is a valid answer, but when applying it raw to a transform like transform.eulerAngles = new Vector3(pitch, 0, yaw) wouldn't get the expected result because the rotation will (as a rough explanation) be Quaternion.Euler(pitch, 0, 0) * Quaternion.Euler(0, 0, yaw) but the multiplication should be the other way around. which leads us to:

 yaw = -asin(normal.x)
 pitch = atan2(normal.z, normal.y)


Edit:

Thank you for clarifying your question.
What you want to do is way more straight forward than the story above.
The target is to get the forward direction vector of the slope, which can be converted in to a rotation.
You can use the cross product to get the right (as in direction) vector by doing the cross product of the normal and the up direction.
With the normal and the right vector you can do a cross product again to get the forward vector.

Which in code looks like:
 static Vector3 Normal2Forward(Vector3 normal, Vector3 up)
 {
     var right = Vector3.Cross(normal, up);
     return Vector3.Cross(normal, right);
 }
 
 void Foo()
 {
     var forward = Normal2Forward(hit.normal, Vector3.up);
     var rotation = Quaternion.LookRotation(forward, Vector3.up);
 }
Comment
Add comment · Show 4 · 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 Reconnoiter · Aug 15, 2017 at 01:24 PM 0
Share

Hi @hoekkii , hi @andrew-lukasik ,

Thanks both of your for your suggestions, however they don't entirely do what I am trying to achieve (almost though). Sorry for being a bit unclear earlier. I want to use this to attach objects to surfaces/floors/terrain, however I want to let the objects always face the direction of the slope. I can explain this better with an image (the green arrow is the direction the object should face on the respective slope): alt text

avatar image hoekkii · Aug 16, 2017 at 10:29 AM 0
Share

I updated the answer ;)

avatar image Reconnoiter · Aug 17, 2017 at 12:57 PM 0
Share

Thanks for your clear & comprehensive way of explaining. On top of that your code/solution is very clean. :-)

avatar image Reconnoiter · Aug 18, 2017 at 11:51 AM 0
Share

Hi @hoekkii , I noticed you made a little error in your code. It should be Vector3 right = Vector3.Cross(normal, up*-1); (you missed the * -1), otherwise all the objects are placed backwards.

avatar image
1

Answer by andrew-lukasik · Aug 14, 2017 at 07:33 PM

 //calculate generalDirection:
 Vector3 generalDirection = Vector3.ProjectOnPlane( hit.normal , Vector3.up ).normalized;
 
 //generalDirection will be of length 0 when normal is parrallel to Vector3.up (flat terrain etc)
 if( generalDirection==Vector3.zero)
 {
     //use predefined direction instead (or whatever suits your need):
     generalDirection = new Vector3( 1f , 0f , 1f ).normalized;
 }
 
 //calculate preciseDirection:
 Vector3 preciseDirection = Vector3.ProjectOnPlane( generalDirection , hit.normal ).normalized;
 
 //calculate rotation:
 Quaternion rotation = Quaternion.LookRotation( preciseDirection , hit.normal );
Comment
Add comment · Show 1 · 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 Reconnoiter · Aug 17, 2017 at 12:59 PM 0
Share

Thanks!___

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

70 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 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 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 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 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 avatar image avatar image avatar image avatar image avatar image

Related Questions

RaycastHit.normal and Orientation to a Path 1 Answer

Get Material of Normal? 0 Answers

Resetting RaycastHit normals in code? 1 Answer

RaycastHit.normal problem 0 Answers

default cylinder to indicate hit.normal 1 Answer


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