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 ronronmx · Apr 30, 2012 at 03:06 AM · rotationquaternioneulerangles

Using Quaternion.LookRotation( ) on y axis only, but keep x axis of transform the same?

The problem I have is a little different than what I have read about concerning the same issue. I found plenty of answers showing how to only rotate on 1 axis when using functions like 'Quaternion.LookRotation()', and I can achieve that just fine. My problem is that the object I am rotating towards the target is a motorcycle, which also rotates on the X axis for forward/backward pitch.

When I limit the rotation to the y axis only, and zero out the other 2, my motorcycle rotates towards the target on Y just fine, but it's X axis rotation is now locked to 0...so when going up-hill or down-hill, the bike doesn't rotate anymore.

If I don't zero out the X axis for the rotation, the the bike's X axis rotation is also following the target, so if my bike is going up-hill and the next waypoint is at y = 0 (on the ground), then the bike's X rotation tries to point towards the waypoint and rotates the opposite way of the up-hill, down-hill.

I have hit a roadblock trying to figure out how to leave the bike's X rotation alone while making its Y axis follow waypoints. Here's what I have so far:

 void Update () 
 {
     // Loop through waypoints
     if( currentWaypoint < waypoints.Length )
     {
         // Get direction of next waypoint
         Vector3 direction = waypoints[currentWaypoint].position - transform.position;
             
         // Check if we passed the current waypoint and get the next one if we did
         if( transform.position.x > waypoints[currentWaypoint].position.x )
         {
             currentWaypoint++;
         }
         else
         { 
             Quaternion newRotation = Quaternion.LookRotation( direction );
             Quaternion rot = Quaternion.Slerp( transform.rotation, newRotation, 
             transform.parent.rigidbody.velocity.magnitude * Time.deltaTime );
                 
             transform.rotation = rot;

             // This version below gives me the bike's X rotation bike, but I gimbal lock problems...
             //transform.rotation = Quaternion.Euler( transform.eulerAngles.x, rot.eulerAngles.y, 0.0f );    
         }
     }
     else
     {
         Debug.LogWarning("NO MORE WAYPOINTS TO FOLLOW");
     }
 }

Quaternions give me a headache :) I've been trying to get this to work for the past week, and although I am really close, it's still not stable enough to be used.

If any of you rotation gurus out there can give me some much needed help, I would really appreciate it! Thanks for your time,

Stephane

Comment
Add comment · Show 2
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 Seth-Bergman · Apr 30, 2012 at 03:21 AM 0
Share

try updating your direction Vector3 before creating the "newRotation"..

Vector3 direction = waypoints[currentWaypoint].position - transform.position;

direction.x = (plug in the desired height here);

etc.

I suppose you may then need to multiply the desired height by the distance from the next waypoint, to keep it constant..

as in: direction.x = ((height * Vector3.Distance(waypoints[currentWaypoint].position,transform.position)) / someConstant);

avatar image ronronmx · Apr 30, 2012 at 05:58 PM 0
Share

I'll give that a try and see if I can make it work. I wish there was a way to multiply my oldrotation by my new rotation, so that if my new rotation's x was 0, mutliplying it with the old rotation would only return the old roation's x. Is this possible?

Thanks for the example above Seth, I'll let you know if I can make this work!

2 Replies

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

Answer by ronronmx · May 01, 2012 at 05:42 AM

I got the rotation to work the way I needed it to work, so for future reference here it is below (I tried both solutions given above with no success for my particular situation, but thanks anyways guys):

 // Get direction of next waypoint
 Vector3 direction = waypoints[currentWaypoint].position - transform.position;
             
 // Check if we passed the current waypoint and get the next one if we did
 if( transform.position.x > waypoints[currentWaypoint].position.x )
 {
     currentWaypoint++;
 }
 else
 { 
     Quaternion newRotation = Quaternion.LookRotation( direction.normalized );
     float yAngle = Mathf.LerpAngle( transform.eulerAngles.y,newRotation.eulerAngles.y - 90, rBody.velocity.magnitude * Time.deltaTime );
                 
     rigidbody.MoveRotation( Quaternion.Euler( 0, yAngle, transform.eulerAngles.z ));
 }


Hopefully this can help anyone else in the same situation :)

Stephane

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
2

Answer by aldonaletto · Apr 30, 2012 at 03:50 AM

Usually you should use a parent/child hierarchy: the parent rotates around the Y axis and the child rotates locally around X - doing both rotations with the same object is complicated, because the first rotation also rotates the axes, and the second rotation gets tilted.
But in your specific case - a two wheel vehicle - there's a simpler and smarter solution: find the horizontal direction and cast two rays to the ground, one ahead and the other behind the bike; define a vector from back hit point to forward hit point and assign it to transform.forward:

  ...
  else {
    RaycastHit hitFwd;
    Physics.Raycast(transform.position + direction.normalized, -Vector3.up, out hitFwd);
    RaycastHit hitBck;
    Physics.Raycast(transform.position - direction.normalized, -Vector3.up, out hitBck);
    Vector3 dirXY = (hitFwd - hitBck).normalized;
    float speed = transform.parent.rigidbody.velocity.magnitude;
    transform.forward = Vector3.Lerp(transform.forward, dirXY, speed * Time.deltaTime);
  }
  ...
NOTE: this algorithm was suggested by @SirGive in the question http://answers.unity3d.com/questions/168097/orient-vehicle-to-ground-normal.html
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 ronronmx · Apr 30, 2012 at 05:52 PM 0
Share

Aldo, thanks for the example code, this is a nice alternative, but I forgot to mention that I'm using a rigidbody to control the bike, and I'm doing all my current rotations (excluding the one I'm trying to add right now) on the rigidbody by adding torque to the Z axis to rotate the bike forward/backward with input, and the rigidbody takes care of pitching the bike when the terrain underneath changes.

Since the Quaternion.LookRotation() function points the transform's forward axis towards the target, and that my rigidbody's transform goes forward on the X axis (I'm using transform.right for all forward/backward movements), I had the create a child object and rotate it's Z axis so that it points the same way as my rigidbody's X axis, and childed all other transforms to that new object.

I am perfor$$anonymous$$g the turning code above on the new child object. $$anonymous$$aybe I should change my code to perform all forward/backward movement on the Z axis ins$$anonymous$$d of X, or maybe I can use a different method to turn the bike which doesn't rely on the Z axis to be pointing in the direction my bike is moving?!

avatar image anthot4 · May 31, 2018 at 01:08 PM 0
Share

@aldonaletto How would you do this with three axis? I am trying to create a rotation button in my game with three seperate axis. Is is best to have a heirchy tree with a parent, child and grandparent with each gameobject for a seperate axis rotation?

avatar image aldonaletto anthot4 · Jun 01, 2018 at 07:09 PM 0
Share

Yes, make a 3 level hierarchy where each level rotates about its local axis (X, Y or Z), like this:

   AxisX    // Rotate(x,0,0)
     AxisY    // Rotate(0,y,0)
       AxisZ   // Rotate(0,0,z)

Rotate assumes local axes by default (Space.Self)

avatar image anthot4 aldonaletto · Jun 02, 2018 at 12:19 PM 0
Share

Thanks i'll give that a try.

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

6 People are following this question.

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

Related Questions

Alternative to Quaternion.LookRotation() ? 2 Answers

Writing a custom LookAt() function 2 Answers

Keeping track of vehicle rotation? 1 Answer

Rotating local transform not rotating fully if tranform.up is not exactly at (0,1,0) 1 Answer

Basic quaternion question 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