Wheel Friction Curve and PhysX, a discussion about settings.

Hi everyone.

I did a google search for information on the PhysX WheelCollider’s Wheel Friction Curve and settings. I came across some interesting differences in settings that the programmers out there are using when compared to the initial settings in Unity when you create a WheelCollider.

Now I have read in these forums a post from the Unity guys that they just ported the WheelCollider as is into unity from PhysX and there was little to no documentation. When you create a WheelCollider your initial settings for Friction are as follows,

Forward Friction and Sideways Friction

Extremum Slip = 1
Extremum Value = 20000
Asymptote Slip = 2
Asymptote Value = 10000
Stiffness Factor = 1

Now here are some of the values I have found in my search.

Extremum Slip = 0.01
Extremum Value = 1.0
Asymptote Slip = 0.04
Asymptote Value = 0.6
Stiffness Factor = 50000

Extremum Slip = 1.0
Extremum Value = 0.02
Asymptote Slip = 2.0
Asymptote Value = 0.01
Stiffness Factor = 800000

Extremum Slip = 1.0
Extremum Value = 0.01
Asymptote Slip = 0.6
Asymptote Value = 0.04
Stiffness Factor = 6000 Lng/ 4000 Lat Wheels with Traction
Stiffness Factor = 5000 Lng/ 1000 Lat Wheels without Traction

As you can see there is a huge difference in numbers for Stiffness, Extremum Value and Asymptote Value.

I’ve tried some of these settings using the Race Demo and creating a huge flat plane to drive across for high speed turns and handbrake slides. These settings seem to work well.

Food for thought/discussion.

Well according to this website, http://awakenedmmo.org/docs/physx/html/class_nx_tire_function_desc.html , The default values for the Wheel Friction are as follows.

Extremum Slip = 1.0
Extremum Value = 0.02
Asymptote Slip = 2.0
Asymptote Value = 0.01
Stiffness Factor = 1000000

Now if you move the decimal point for stiffness over by a factor of 6 so it equals 1, and then move the two values over by 6 then you have the default settings in Unity. I wonder which setup is better to start with.

My advise at this point is not to expect too much from the PhysX wheel colliders, unfortunately. The physX implementation (which we don’t really have any control of) is imprecise and contains errors. Possibly this will eventually be changed in an update to PhysX, but right now, the best bet is to create a custom wheel collider based on raycasts. I am working on some sample code on how to do that, but that is currently a side project next to my main line of work, so it may well take a while for that to be released.

Do you think an object with a cylinder collision mesh, and using rotation forces on it etc, would work well for wheels?

(Heh guess there’s one way to find out!)

Defintely not! The built-in wheel collider will still get you much further then that. A car’s wheel is a very complex physical entity, and not at all trivial to simulate.

Just to add some balance here, I jumped right in using Unity’s wheel colliders for my first few projects, and I’ve had no trouble with them save for the expected initial tweaking and adjusting that comes with working with any physics set-up.

Here’s one of my first car test scenes. Press “C” to change the view to outside the car.

The suspension, wheel grip, etc all work fine. So - it can be done!

http://dev.skivecreative.com/duck/unityTest/car/

  • Ben

@duck
The demo is pretty interesting, however i couldn’t help but notice everytime i hit a ramp, i’d land on my nose or generally come down too fast and not gain any altitude. Maybe i play too many other games or watch too many movies to know what is realistic.

Sure, it’s not mean to be particularly realistic in terms of gravity or grip, it was more a simple demo of how the wheel colliders can be made to behave in a somewhat sane manner in a fairly short amount of time.

And I was certainly not contesting that! The wheel colliders are useful for what they are - a simple means of getting basic wheel physics in Unity. It’s just that when you want realistic car physics, you will quickly grow beyond the built-in WheelCollider, and that’s where you’ll need to invent something of your own.

What particular functionality do you find the wheelCollider to be missing? It has separate longitudinal and lateral friction curves, suspension, motor torque, braking, steering. I’m genuinely interested to hear in which situations you might outgrow these features.

And in addition, I would love to hear about it if someone comes up with an improved wheel system. Please post in this thread if you do!

I have written quite a few home-made implementations of wheel physics over the past few years, however being fairly new to Unity, I am enjoying being able to hand over this particular area of functionality to Unity’s wheelCollider and focus my attention on other details of the project!

  • Ben

(edit: typo)

I just wish I could figure out how to accurately match the wheel meshes to the movement and state of the colliders. I got rotation roughly done, and steering…but shocks etc? NO idea how to do that! So my cars never look quite right! (plus it’s really hard to tell what is going on )

Well, just like the threads I have read from programmers using Nvidias PhysX Engine outside of Unity 3D, there seems to be two camps. Those that use the WheelColliders and get them to work well for their purposes and those that do not like the WheelColliders at all.

I think what we need is a good discussion to try and understand the WheelColliders and the best way to use them.

One suggestion that I have seen a few times is to find settings for Slip and Value then adjust the stiffness depending on speed and/or surface to get the desired effect. Has anyone tried to do this and how would this best be done?

I have a set up where I can adjust every input of forward and sideways friction based off of factors such as speed, steering angle, directional magnitude, etc. and I am seeing much better results by being able to change the wheel friction curve to better suite the situation.

I do not believe a single setting is capable of fulfilling all situations and I think that is where most people get frustrated using the Wheel Collider.

Thoughts anyone?

Hi all,

I find this thread very interesting as I’m trying to make deep research in wheel colliders functionality and what can be done, mainly for games.

That’s the reason I built up a test tool for car setup using wheel colliders and I’ll improve as I have time.

See this post for it:

http://forum.unity3d.com/viewtopic.php?t=27048

You can try there from very soft to extreme values and get resulting values for several parameters.

I included the AI for the car to best see minute differences as you move the sliders, but you can deactivate it and drive on your own pressing “i”. Also try the interactive camera (press “c”).

As part of the tool I will include sliders for Extremum and Asymptote values and try to make some presets for certain car behaviors like drifting.

Hope it will bring some light and please post any interesting thing you find.

Thank you

Thanks for chiming in ikiman. Hopefully we can get the wheel collider scripting figured out soon. Your tool is an excellent start.

Wow, thanks for researching these alternate settings. Using them, I was able to get rid of a problem that was plaguing me where placing acceleration on two rear wheelcolliders caused the whole car to pull to the left on a very flat surface. I’ll have to play some more with it, but changing the settings to that first alternate seems to have gotten rid of the pull to one side!

Here’s an Editor script that I wrote to switch between these alternate friction settings quickly. Place it in Assets\Editor\ChangeWheelColliderSettings.cs, and then go to Custom > Wheel Colliders > … with one or many wheel colliders selected.

using UnityEngine;
using UnityEditor;

// Alternate settings found at [url]http://forum.unity3d.com/viewtopic.php?t=26405[/url]


public class ChangeWheelColliderSettings : ScriptableObject {
   
    [MenuItem ("Custom/Wheel Collider/Change to Alternate 1")]
    static void ChangeWheelColliderSettings_Default1 ()
    {
    		SelectedChangeWheelColliderSettings_Default1();
    }
    
	[MenuItem("Custom/Wheel Collider/Change to Alternate 2")]
	static void ChangeWheelColliderSettings_Default2 ()
	{
		SelectedChangeWheelColliderSettings_Default2 ();
	}
	
	[MenuItem("Custom/Wheel Collider/Change to Alternate 3")]
	static void ChangeWheelColliderSettings_Default3 ()
	{
		SelectedChangeWheelColliderSettings_Default3 ();
	}
	
	[MenuItem("Custom/Wheel Collider/Change to Unity Default")]
	static void ChangeWheelColliderSettings_Default ()
	{
		SelectedChangeWheelColliderSettings_Default ();
	}
	
    // ----------------------------------------------------------------------------
   
    static void SelectedChangeWheelColliderSettings_Default1 ()
    {
   
        Object[] colliders = GetSelectedWheelColliders ();
    		//Selection.objects = new Object[0];
	    	foreach (WheelCollider collider in colliders) {
			WheelFrictionCurve curve = new WheelFrictionCurve();
			curve.extremumSlip = 0.01f;
			curve.extremumValue = 1.0f;
			curve.asymptoteSlip = 0.04f;
			curve.asymptoteValue = 0.6f;
			curve.stiffness = 50000.0f;
			collider.forwardFriction = curve;
			collider.sidewaysFriction = curve;
        }
    }

	static void SelectedChangeWheelColliderSettings_Default2 ()
    {
   
        Object[] colliders = GetSelectedWheelColliders ();
    		//Selection.objects = new Object[0];
	    	foreach (WheelCollider collider in colliders) {
			WheelFrictionCurve curve = new WheelFrictionCurve();
			curve.extremumSlip = 1.0f;
			curve.extremumValue = 0.02f;
			curve.asymptoteSlip = 2.0f;
			curve.asymptoteValue = 0.01f;
			curve.stiffness = 800000.0f;
			collider.forwardFriction = curve;
			collider.sidewaysFriction = curve;
        }
    }
   
	static void SelectedChangeWheelColliderSettings_Default3 ()
    {
   
        Object[] colliders = GetSelectedWheelColliders ();
    		//Selection.objects = new Object[0];
	    	foreach (WheelCollider collider in colliders) {
			WheelFrictionCurve curve = new WheelFrictionCurve();
			curve.extremumSlip = 1.0f;
			curve.extremumValue = 0.01f;
			curve.asymptoteSlip = 0.6f;
			curve.asymptoteValue = 0.04f;
			curve.stiffness = 6000.0f;
			collider.forwardFriction = curve;
			curve.stiffness = 4000.0f;
			collider.sidewaysFriction = curve;
        }
    }
	
	static void SelectedChangeWheelColliderSettings_Default ()
    {
   
        Object[] colliders = GetSelectedWheelColliders ();
    		//Selection.objects = new Object[0];
	    	foreach (WheelCollider collider in colliders) {
			WheelFrictionCurve curve = new WheelFrictionCurve();
			curve.extremumSlip = 1.0f;
			curve.extremumValue = 20000.0f;
			curve.asymptoteSlip = 2.0f;
			curve.asymptoteValue = 10000.0f;
			curve.stiffness = 1.0f;
			collider.forwardFriction = curve;
			collider.sidewaysFriction = curve;
        }
    }	
    static Object[] GetSelectedWheelColliders()
    {
        return Selection.GetFiltered(typeof(WheelCollider), SelectionMode.DeepAssets);
    }
}

Hi Jonas, did you ever get anywhere with the sample code ?
I’m looking at creating a custom wheel collider with sphere casts instead of the standard ray casts but have no idea where to start creating a custom collider to be honest.

Hey, can you update the link so I can find the thread? I’m genuinely interested in what I can learn from this, especially the AI logic you speak of.