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
1
Question by littlelingo · Dec 09, 2009 at 11:46 PM · normals

How to get Quaternion.FromToRotation and hit.normal to allow the Y-axis to not be set to 0

I implemented a terrain follow script that looks like this:

var fwd:Vector3 = transform.TransformDirection(Vector3.forward); var up:Vector3 = transform.TransformDirection(Vector3.up);

 transform.localPosition += fwd/speedModifier;

 var hit:RaycastHit;
 Debug.DrawRay(transform.localPosition, -up*20, Color.cyan);
 if (Physics.Raycast(transform.localPosition, -up, hit, 10)){

     if ( hit.distance > 1 ){
         transform.localPosition.y -= hit.distance-1;
     } else if ( hit.distance < 1 ){
         transform.localPosition.y += 1-hit.distance;
     }

     var rot:Quaternion = Quaternion.FromToRotation(Vector3.up, hit.normal);
     transform.rotation = rot;

 }

The issue I am running into is when setting the rotation of the transform it is always snapping the GO on the Y-axis to 0 instead of using the Y-axis rotation already applied (for example 180). I have tried a bunch of different things which either gave undesirable results or setting the Y-axis to 0.

Essentially, how can I get the hit.normal and apply it to the GO transform via Quaternion.FromToRotation and it not snap the Y of the transform?

Thanks in advance!

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

3 Replies

· Add your reply
  • Sort: 
avatar image
9

Answer by Jaap Kreijkamp · Dec 13, 2009 at 01:22 AM

Let's try it again, now read what you want, function below should do the trick. What it does is calculating a projection of the GO's forward vector on plane defined by normal vector of hit, then generate a rotation that looks in direction of the projection vector and has the normal vector as up vector.

var speed = 0.5;

function Update () { var fwd:Vector3 = transform.forward;

 transform.position += fwd * speed * Time.deltaTime;

 var hit:RaycastHit;
 // instead of -Vector3.up you could use -transform.up but as hit point will jump
 // when slope changes it will give jitter. That's solvable as well by working from
 // a pivot point in bottom centre of object instead of centre (and to make sure
 // your raycast won't be too low move start pos back by a bit using again
 // transform.up as direction.
 if (Physics.Raycast(transform.position, -Vector3.up, hit, 10)){

     if ( hit.distance > 1 ){
             transform.localPosition.y -= hit.distance-1;
     } else if ( hit.distance < 1 ){
             transform.localPosition.y += 1-hit.distance;
     }

     var proj : Vector3 = fwd - (Vector3.Dot(fwd, hit.normal)) * hit.normal;
     transform.rotation = Quaternion.LookRotation(proj, hit.normal);
 }

}

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 littlelingo · Dec 15, 2009 at 03:19 AM 0
Share

Jaap, Thank you for the reply it worked very well!

avatar image formidable · May 15, 2012 at 11:58 PM 0
Share

How do you move the pivot point?

avatar image Sake906 · Apr 16, 2014 at 08:31 PM 0
Share

I've been searching ALL NIGHT for the solution to this extremely common problem. Finally found it over here, thank you very much Jaap!

avatar image plingativator · Nov 24, 2015 at 05:36 PM 0
Share

Saved my evening too! Every other solution I found wasn't working for me but this one finally did the trick for setting proper direction when moving around on my planetoid.

avatar image
2

Answer by Weblyan · Jan 07, 2017 at 08:22 PM

Adding to Jaap's Answer. I had the same problem with the y-rotation snapping when i tried to align something with the terrain.

         public static void AlignTransform(Transform transform)
         {
             Vector3 sample = SampleNormal(transform.position);
            
             Vector3 proj = transform.forward - (Vector3.Dot(transform.forward, sample)) * sample;
             transform.rotation = Quaternion.LookRotation(proj, sample);
         }
 
         public static Vector3 SampleNormal(Vector3 position)
         {
             Terrain terrain = Terrain.activeTerrain;
             var terrainLocalPos = position - terrain.transform.position;
             var normalizedPos = new Vector2(
                 Mathf.InverseLerp(0f, terrain.terrainData.size.x, terrainLocalPos.x),
                 Mathf.InverseLerp(0f, terrain.terrainData.size.z, terrainLocalPos.z)
             );
             var terrainNormal = terrain.terrainData.GetInterpolatedNormal(normalizedPos.x, normalizedPos.y);
 
             return terrainNormal;
         }

This does not use a raycast to get the normal. and instead gets the normal from the terrain data.

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 Unityfordummies · Feb 17, 2019 at 05:16 PM

Thank you so much @Weblyan. I spent hours looking for a way to do that.

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

What are normals? 1 Answer

How can I get back a hit? 1 Answer

duplicate and flip mesh in code 5 Answers

Only assignment, call, increment, decrement, and new object expressions can be used as a statement 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