Wheel Controller 3D - Customizable Three Dimensional Alternative to WheelCollider

Wheel Controller 3D is a complete alternative to the Unity’s inbuilt wheel collider.
It allows for more realistic vehicle behavior, more customization and most importantly - improved ground detection. See for yourself:

WebGL Demo (all the assets in the demo are included)
Website & Video
Auto-generated Documentation

Features:
• Wheel has width and length, not only a single point in the middle.
• API with only minor differences from Unity’s inbuilt WheelCollider - easily swappable.
• Fully customizable via custom inspector. Adjust spring, damper, friction curves, geometry, etc.
• Adjustable camber, caster and rim offset.
• Pacejka friction model with support for different surfaces.
• Fully adjustable at runtime.
• Adjustable ground detection resolution.
• Can handle wheel visuals by itself (rotation and position).
• Suitable for different kinds of vehicles: cars, trucks, motorcycles, tanks, etc.
• C# (OOP) with documentation and API reference.
• Source code included.

Screenshots:

3D ground detection:

Realistic suspension with camber and rim offset:

Ground detection over the whole bottom surface of the wheel:

Custom inspector:

API similar to the Unity’s wheelcollider for easier use and existing project conversion:

A lot of development time went into this asset so I really do hope you like it.
Also, suggestions for improvements are alway welcome.

This asset is now available at the Unity Asset Store.

4 Likes

Looks great but is this asset limited to four wheels or does it work with more or less wheels?

It works with multiple wheels. I have tested it on a vehicle with 8 wheels but there is no hard limit.

Hi,

We’re working on a robot simulation. The physical robot has encoders on its motors to measure how much the motor actually rotated.
We’re looking for an alternative to Unity’s wheelCollider to do that. Specifically, we need these features:

  1. Start the wheel and get a constant speed instantly (almost), like small electric motors do.
  2. Maintain a constant speed.
  3. Get an exact measurement of the motor rotation.

Does Wheel Controller 3D support these features?

Thanks.

It supports the same features as the inbuilt wheel collider plus customizable curves (spring, damper, friction) and three-dimensional collider. It was primarily built for vehicles so I cannot guarantee that it will work on your robot.
1.) Wheel speed is controlled via torque (be it motorTorque or brakeTorque or both at same time), so there is no way to set RPM to one value out of the box.
2.) Maintaining the speed is up to the vehicle that controls the wheels. Wheels add forces to the rigidbody based on torque, terrain setup and surface but don’t do any driving logic themselves.
3.) wheelController.rpm is available in the same way as wheelCollider.rpm

So no, I would not suggest it.

Purchased this yesterday, finding it really useful so far. A couple of issues/fixes:

1/ spring.compressionPercent should be 0 when airborne not 1.
2/OnDrawGizmos does not have a null guard for wheel.visual - causes lots of null reference exceptions.

Cheers,
Chris

Version 1.3 is on its way so I will add those two to the todo list for 1.4. Both are simple fixes.
Also note that 1.3 brings some improvement to handling overall.

I had some stability issues to fix so v1.4 is on it’s way - along with bug fixes for these two.

v1.4 Change log:

  • Solved any remaining stability issues - vehicles are now stable with much broader range of damper values.
  • Minor API and documentation updates.
  • Replaced demo map - WebGL demo should run better on PCs with weaker hardware.

Hi!

Thank you for this wonderful asset.
Please tell how to setup the car for drifting. I noticed a strange thing - if you use a front-wheel drive, the drift is possible, if rear - no, although it should be Vice versa.

And another question - can you share the extended test scene?
Thanks.

Glad you like it so far :smile:

As for drifting - that is due to the force being applied equally to the both (rear) wheels which is not the case in a “normal” RWD car. The asset that I’m developing at the moment is using WC3D and as soon as I implemented a simple differential at the rear things got to behave like they should. What is happening in a real with a real differential is one rear wheel losing traction either due to (1) too much torque or (2) too stiff differential where the wheel on the outside spins faster and makes wheel on the inside lose traction which results in so called “oversteer”. Try applying torque to only one of the rear wheels and you will see different behavior from what you have at the moment.

I tried re-downloading the package from the store and it seems that I forgot to activate camera before deploying - oh my.

If by extended you mean the old one - no problem. Send me a mail and I will send it over. Also, I will include both scenes in the next version.

Thanks a lot, Aron!

You gave a chance to my project that almost died due to the fact that the standard wheel physics in Unity 5 is completely unusable.
About the differential I understand you, I will try.
Should be possible to chat with you privately about the source code?
My email:

Of course.There is a “Support mail” link on my publisher page: http://u3d.as/hjt
I would suggest you remove your email from the forums or you might get a lot of spam from all the bots.

I already submitted for review corrected scene with pre v1.4 terrain (one in the YouTube video). Those guys doing asset store reviews must love me since I give them something to do all the time…

Hi NWHCoding, just playing with the latest version and still have a few niggles:

1/I use a skinned animation to control my suspension and then rotate my wheel on top of that so I do not want to set a wheel visual. This currently gives me a warning every frame in the editor. (I have just commented this out and replaced it with a null guard.)

2/There seems to be a bug still with springCompression which sometimes seems to return odd values. I was initially using this to drive my suspension animation, but it occasionally seems to snap to full extension when bouncing which looks very wierd. Your wheel visuals work fine so I hacked in a bit of code to get me the normalized spring length and this works absolutely fine: public float GetNormalizedSpringLength() { return spring.length / spring.maxLength; } I’m guessing there must be a state in which springCompression is being set incorrectly but for some reason the spring.length is always fine??

Other than that though the latest version does feel like a big improvement. Keep up the great work.

Cheers,
Chris

Hi NWHCoding,

Another bug -

I have a basic brakeTorque of 10 always being applied to simulate drive train losses. When I brake hard I apply a brake torque of 700.

If vehicle becomes airborne with brakeTorque at 10 the wheel will slowly come to a stop as expected. If however the wheel has stopped spinning and I then brake (apply a brakeTorque of 700) whilst still airborne, the wheels remain stationary, but when I release the brake and the brakeTorque then returns to 10 the wheels start spinning backwards forever (until it hits the ground).

Edit - Looks like it’s this:
(A quick hack to only call this when hasHit solves the problem (although I never use MotorTorque))

// Calculate residual (wheel-spinning) force that could not be put to ground
        var residualForce = 0.0f;
        if (Mathf.Abs(combinedForce) > Mathf.Abs(availableForwardForce))
            residualForce = Mathf.Sign(combinedForce) * (Mathf.Abs(combinedForce) - Mathf.Abs(availableForwardForce));
        wheel.residualAngularVelocity = ((residualForce * wheel.tireRadius) / wheel.inertia) * Time.fixedDeltaTime;

Thanks,
Chris

I will look into it, but springCompression should return what you need. Looking into code it is effectively 1f - (spring.availableLength / spring.maxLength); in v1.4. That will go to 1 if the vehicle is either not hitting ground or tipped over.

Version 1.5 is coming out in a few days and will solve a problem with one-frame-late calculation of wheel world position which might fix your problem along the way. Send me a mail and I will send updated version to you.

Wow, that is one specific bug you got there. Glad you informed me about this.

Regards,
Aron

I have your wheel controllers strapped to an aircraft :slight_smile:

Oh my. Explains some things I guess…

Also, v1.5 is out.

Hi, I just bought this asset. It’s very simple to setup it even in a big project and I like it. Thanks)

But I got a problem with layers (layer #20). That is not good way for me coz all my vehicles has own layers (Enemy, Ally, etc.) also not only the car should be ignored.
As I saw in code this layermask is defined as local var in WheelScan function, so I can suggest to move it as variable, so users can override/set it manually.
It’s not a problem for me to remake it for my project (also my modification of it will be broken after asset update), just want you keep in mind this problem.

Cheers.

I’m still reading the documentation and trying to fix a problem with jittery wheels in some positions.
UPD. The problem was in layermask.

rimCollider.radius = tireRadius * 0.5f;

I suppose the radius of rim collider will be as Rim Radius parameter. I have 0.63 wheel and rim should be 0.4 for it, so I made modification:

rimCollider.radius = rimRadius;

I hope it doesn’t break any part of physics.