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 DanMarionette · Jan 13, 2012 at 09:16 PM · rigidbodyconstraintsspline

Constraining Rigidbody to Spline

Hi,

I have a basic car setup with a rigidbody and four wheel colliders. I want the car to move forward and jump whilst being constrained to a spline created with super spline. I have managed to get various different solutions almost working but always run into problems. The car drifts away from the spline as it travels around corners at speed. I have tried adding forces to move it back towards the spline but nothing works quite right.

Any advice on a setup would be appreciated.

Thanks

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

4 Replies

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

Answer by DanMarionette · Jan 17, 2012 at 10:33 AM

Thanks Winterblood for all your help and advice. In the end I have got a solution that seems to work pretty well. I have included the main functions that are involved with the movement and position of the rigidbody and also FixedUpdate() as the order in which the functions are called proves to be important.

 void FixedUpdate()
 {
     UpdateSplinePositionAndRotation();
     HandcarRotation();
     SetToSplinePosition();
     WheelTorque();
 }
 
 void UpdateSplinePositionAndRotation()
 {
     //fetch and store the spline position and rotation for other functions to use for optimisation
     float splinePoint = spline.GetClosestPoint(myTransform.position, splineAccuracy);
     splinePosition = spline.GetPositionOnSpline(splinePoint);
     splineRotation = spline.GetOrientationOnSpline(splinePoint);
 }
 void HandcarRotation()
 {    
     float rotationX = myTransform.rotation.eulerAngles.x;
     float rotationY = splineRotation.eulerAngles.y;
     float rotationZ = myTransform.rotation.eulerAngles.z;
     
     myTransform.rotation = Quaternion.Euler(rotationX, rotationY, rotationZ);
 }
 
 void SetToSplinePosition()
 {
     //set the local x velocity to zero to help prevent sliding off the spline
     Vector3 localVelocity = myTransform.InverseTransformDirection(myRigidbody.velocity);
     localVelocity = new Vector3(0f, localVelocity.y, localVelocity.z);
     myRigidbody.velocity = myTransform.TransformDirection(localVelocity);
     
     //set handcar position onto spline
     Vector3 position = new Vector3(splinePosition.x, myTransform.position.y, splinePosition.z);
     myTransform.position = position;
     
     //freeze localz rotation
     Vector3 localRotation = myTransform.localRotation.eulerAngles;
     localRotation = new Vector3(localRotation.x, localRotation.y, 0f);
     myTransform.localRotation = Quaternion.Euler(localRotation);
 }
 
 void WheelTorque()
 {
     frontLeftWheel.motorTorque = speed;
     frontRightWheel.motorTorque = speed;
     backLeftWheel.motorTorque = speed;
     backRightWheel.motorTorque = speed;
 }
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 Winterblood · Jan 13, 2012 at 11:25 PM

Sounds like you have two systems fighting each other. Unity's physics will try to make the car behave naturally, while your spline constraints are trying to keep it on the track no matter what. I'd set it up like this:

  • give the car a script that makes it steer towards a target as if the player was driving it (eg. feed fake input axes into it which turn the wheels), under normal physics.

  • have another script find the nearest point to the car on the track spline. Then look X units ahead along the spline, and feed that position into the steering script as a target.

This will make the car drive naturally and self-correct onto the track even if pushed off by the player. Expose some floats to control how hard the car turns and accelerates towards the target, and how far ahead of the car the target is, and you should be able to tweak it to navigate the track pretty well.

Note: it would be easier to just move the target along the spline at some fixed speed, but that will go wrong if the car is slowed down or catches up on a long straight. If you always find the nearest point and look ahead from that, it will work no matter how much the car's speed varies.

Further note: finding the nearest point on the spline is quite complex, and can go wrong if the spline crosses itself (eg. a figure eight) or nearly does. The mathematical solution for a Bezier spline is a 6th-order differential equation, which is too hardcore for me, so I recommend sampling the spline repeatedly to find the closest point. Shout if you need further help - there's lots of ways to optimize that search.

Comment
Add comment · Show 3 · 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 DanMarionette · Jan 14, 2012 at 04:11 PM 0
Share

Thanks for your quick response. This is actually a method I have been trying. It works for most of the time, even at speed. The problems come in when I want the handcar to jump up a ramp or just simple jump in the air via player control. As this is a handcar on rails I need this solution to be rock solid. Another line I've been going down is creating counter force to stop it from sliding left and right (x axis) but this is proving difficult also. I don't know if my maths is wrong or if I'm not applying the forces correctly. It's a shame because constraining the axis in the rigidbody inspector work well but these don't seem to work for local axis.

avatar image Winterblood · Jan 14, 2012 at 04:51 PM 0
Share

Oh, it's on rails? I think a counter force matched to the local-X component of the handcar's momentum is the right solution, but I'm not sure how the rotational inertia should be handled, to be honest. Try splitting the x force in half and applying each half to one of the two front wheels to give it some twist?

avatar image DanMarionette · Jan 14, 2012 at 05:28 PM 0
Share

I'm using wheels because I want a "realistic" motion when the handcar goes up and over a ramp. In fact that is why I'm trying to use physics but I need the forces to also act on the handcar when it's off the ground so it can jump whilst travelling around a corner. I know that's not realistic but, it's what I would like to achieve if possible. The only other solution is to ditch physics all together but I lose the nice motion when jumping and going over ramps.

avatar image
0

Answer by Winterblood · Jan 16, 2012 at 10:36 PM

Tricky...you could try running it under physics most of the time, but disable the rigidbody when you leave the ground. While disabled you could reposition it using your own simplified physics approximation, and re-enable normal physics when you land. Make sure you update the rigidbody velocity manually while it's disabled, so that it's ready to resume at any point.

Not certain how well that will work, and it certainly isn't efficient. But it would give you more precise control than poking at it with forces...

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 msl_manni · Dec 17, 2012 at 08:27 AM

Hi, Dan Wolley,

I would like to have these functions too ............

 float splinePoint = spline.GetClosestPoint(myTransform.position, splineAccuracy);
 splinePosition = spline.GetPositionOnSpline(splinePoint);
 splineRotation = spline.GetOrientationOnSpline(splinePoint);


Please post more details about these functions as I want to use similar for my project. Thanks, MSL.

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

6 People are following this question.

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

Related Questions

Is it possible to constrain an object's rotation in worldspace? 2 Answers

UnityEngine.Rigidbody does not contain a definition for `contraints' 1 Answer

Bitwise OR vs AND for combining rigidbody constraints 1 Answer

Smoothed Particle Hydrodynamics 0 Answers

holding position 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