• Unity
  • Services
  • Made with Unity
  • Learn
  • 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
  • Forums
  • Answers
  • Feedback
  • Issue Tracker
  • Blog
  • Evangelists
  • User Groups

Navigation

  • Home
  • Unity
  • Industries
  • Made with Unity
  • Learn
  • Community
    • Forums
    • Answers
    • Feedback
    • Issue Tracker
    • Blog
    • Evangelists
    • User Groups
  • Get Unity
  • Asset Store

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 darky · May 04, 2017 at 05:08 PM · rotationquaternionvehiclemotionrotations

Rotate to ground normal and steering direction for a Bicycle?

Hello, so I'm trying to make a bicycle script but I am having trouble with the rotation. I want to rotate the bicycle to my steering direction (where my Front Wheel is facing) while also adjusting itself in Angle to whatever surface the bicycle is on. I have the following code:

 Vector3 smoothNormal = Vector3.up;
 void RotateToSteerAndNormal()
 {
     float rayDistance = 3f;
     RaycastHit hit;
     Vector3 steerDirection;
     Vector3 normal = Vector3.up;
     
     if (Physics.Raycast(frontWheel.position, -Vector3.up, out hit, rayDistance))
     {
         normal = hit.normal;
     }

     // Smooth out the new Normal target
     smoothNormal = Vector3.Lerp(smoothNormal, normal, 3f * Time.deltaTime);

     // Set Steering Direction
     steerDirection = frontWheel.position - frontWheelCOM.position;
     steerDirection.y = 0; // zero y to keep only the horizontal direction

     // Set Rotations        
     var normalRotation = Quaternion.FromToRotation(Vector3.up, smoothNormal);
     var steerRotation = Quaternion.FromToRotation(Vector3.forward, steerDirection);

     // Combine and apply rotations
     transform.rotation = steerRotation * normalRotation;
 }

It works for steering, but the Angle adjustment to the ground normal is bugging out. Here's a video GIF I converted of the problem in action: alt text

Does anyone know how this should be done properly? I need a solution that doesn't affect the steering itself, while still angling to the ground normal as you'd expect.

Comment
Add comment · Show 10
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 FortisVenaliter · May 04, 2017 at 06:16 PM 0
Share

Try reversing the order of operations on the last line:

 transform.rotation = normalRotation * steerRotation;
avatar image darky FortisVenaliter · May 04, 2017 at 06:53 PM 0
Share

That's what I tried originally. It fixes the wrong ground normal orientation, but for some reason it makes the bicycle "slide" away while driving straight onto the ramps. Look here, each time I'm only pressing forward and it slides off by itself: alt text

avatar image FortisVenaliter darky · May 04, 2017 at 07:35 PM 0
Share

Hmmm... that's definitely closer.

Can you please explain this line of code?:

 steerDirection = frontWheel.position - frontWheelCOM.position;

That's the only thing I can see that may cause the sliding, depending on what those two transforms represent.

Show more comments
Show more comments

1 Reply

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

Answer by toddisarockstar · May 04, 2017 at 10:51 PM

have you tryed just setting up colliders and rigidbody restraints to let the physics engine naturally do its work to bring the back wheel down?

i would start by putting two empty child object on both the bottom of the front wheel and back wheel for location reference near where they should be touching the ground.

and then raycast down from each tire to get two points. then calculate the bikes x axis from the two points!

this would be much more accurate than using the grounds normal at one point if the gound has different curves underneath.

Sorry this is untested cause i dont have a bike but this would be the Concept im thinking of:

             Transform frontWheel;
             Transform backWheel;
     
             Vector3 vf;
             Vector3 vb;
             float myX;
     
             // get two points under EACH tire
     
             RaycastHit hit;
             if (Physics.Raycast(frontWheel.position, -Vector3.up, out hit))
             {vf = hit.point;}
             if (Physics.Raycast(backWheel.position, -Vector3.up, out hit))
             {vb = hit.point;}
     
             //get Vector3 direction between two points
             vf = vf - vb;
     
             // convert to angle an get the X axis
             myX = Quaternion.LookRotation(vf).eulerAngles.x;
     
             print ("the X rotation of your bike in eular angles should be : " + myX);
     
     


Comment
Add comment · Show 2 · 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 darky · May 05, 2017 at 01:34 AM 0
Share

Hi Todd, leaving it to Rigidbody/Physics doesn't really work, because if not all 3 Axis are restrained it will easily fall over etc. while leaving only the X Axis unrestrained will lead to jitters since the other Axis still are constrained but want to apply other values to themselves.

I like that you try to average out the two wheels instead of just the one with your code, but I don't see how you'd intend to use it? It doesn't factor in my steering rotations and doesn't get applied to anything. Could you be more specific?

EDIT: I figured it out. This works to apply it:

 Quaternion finalRotation = Quaternion.LookRotation(steerDirection);
 Vector3 finalEuler = finalRotation.eulerAngles;
 finalEuler.x = myX;
 finalEuler.z = 0;
 finalRotation = Quaternion.Euler(finalEuler);
 transform.rotation = finalRotation;

It now does everything as it's supposed to do and I'll mark your answer as accepted. Thank you very much!

avatar image toddisarockstar darky · May 07, 2017 at 02:00 PM 0
Share

Sorry i didn't get back to you sooner. I just had a moment to throw the idea out there at the time. It's cool you got it working. eventually I'm sure you will want the bike to jump of edges or jump ramps. You also might want to think of limiting the distance of the downward raycast so that if the bike or one of it's wheels is ever airborne, It wont keep responding to the ground!

also I noticed in your video that the pivot point of your bike is in the middle of the frame. causing the back wheel to slide slightly left and right when turning. in reality this wouldnt happen with the real phyisics of a bike. The y pivot point of the bike would actually be the back wheel and the front of the bike swings around it based on the steering.

watch a video of someone riding a bike slowly and turning very sharp. The frame is actually rotating around the back wheel!

Of course this would be opposite for something like a fork truck that has the steering in the back. then the back would swing.

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

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

83 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 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

2D animation : problem with rotation interpolation 1 Answer

Where can I learn about quaternions and how to manage rotations in Unity 2 Answers

Look at rotation at a moving object while moving (C#)(2D) 3 Answers

Basic AI Locked Axis 1 Answer

[Solved] Problem with rotation on an Instantiated Object 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges