The Re-Inventing the Wheel Thread

If you want to see how others have implemented the vehicle physics, here are some links:

Unity’s old car tutorial (requires Unity to download and unpack):

There’s advanced vehicle model separately inside that project folder that contains pacejka tire model and it’s own raycast wheels in C# (advanced car part doesn’t use Unity’s wheel colliders).

Here’s someone’s thesis about the subject (most of the basic stuff based on that Marco Monster tutorial I linked earlier):
https://nccastaff.bournemouth.ac.uk/jmacey/MastersProjects/MSc12/Srisuchat/Thesis.pdf

Bullet Physics Engine:

Newton Dynamics Physics Engine:
https://github.com/MADEAPPS/newton-dynamics/blob/master/packages/dCustomJoints/CustomVehicleControllerManager.cpp

Some Unity c# scripts but same basics apply:
http://wiki.unity3d.com/index.php?title=WheelColliderSource (already linked part of this before)
http://wiki.unity3d.com/index.php/VWheelCollider

Also if you want to play with old Pacejka '94 formula, this page explains it pretty well (and contains simplified model as well):

Forgot to mention earlier, there are loads vehicle sim topics at old google group “rec.autos.simulators”: Redirecting to Google Groups
There are lots more if you just browse with the group with keyword physics only, most conversations around that topic seem to be around 2001-2006.

thanks for all the help 0lento
you seem to know a lot about this subject, any chance of a gander at some of your code?

I’d rather not share my own vehicle projects for several reasons. Prototypes I’m currently working on are more of proof of concepts than something that’s usable as is for games. I’ve been doing mostly research for my own game and trying to find optimal solutions for that. I’m also targeting to a very specific handling model (as that’s what my game is all about) so I can’t really share that kind of elements either as I prefer keeping it somewhat unique. :slight_smile:

Even if I did put together some example project, it wouldn’t be that much different from what you’ve already done here (+ I don’t really have enough spare time to clean such thing and/or give support for it).

ok thats fine, totally understand.
thanks again for all the help, couldnt have got this far without it :slight_smile:

it is kind of taking over all my available development time, which is why i put off doing this for so long in the hope that Epic would fix their car, cant understand why they dont really. i knew it would be one of those things that the more you get into it the more there is to learn.
might tidy/finish the next version and leave it there so i can get on with the other million things there is to do for my game(s).

alright here is the last version of this i will give out.
please feel free to use or modify it in any way you see fit. if you find a way to improve it please let everybody know on here.
big credits to and BoredEngineer without whom it would not have been possible :slight_smile:
CarPlugin v0.4

have fun

edit:
@mods, maybe this thread should be moved to “Community Content, Tools and Tutorials”?

Done. And thanks for the plugin, tegleg!

Thank you for the link to friction circle explanation! I was aware about that concept but you’ve got me idea to implement it using ellipse equation. Already added it to the tanks and it works really well.
Link to the math if someone needs it:

I was thinking about something else and perhaps you guys have a better idea. So far as we are using raytrace of sphere trace wheels, we don’t really take into account physical collision of the wheel, in a sense that part of the impact impulse would pass suspension when it’s not aligned with the spring . This could be solved by adding extra collision mesh of the wheel but as it have to be driven kinetically by suspension I have doubts that it would work correctly.
The idea was to manually calculate collision impulse and from there split it into two parts, one that should be absorbed by suspension (shock absorber) and another that should be translated to the chassis. Does it make sense?

thanks for the maths BoredEngineer. i did find that equation before but lost the link.

Tegleg, have you looked at ODE at all

I know that wasn’t directed to me, but do you mean about looking at their vehicle implementation or the whole physics engine? If latter, using a separate physics engine, be it bullet, newton dynamics, ode or whatever is always on option, but their built-in vehicle models are again just their own implementation of it just like physx vehicle is physx’s. It can’t be guaranteed it will be useful for your own game as is. You’ll probably end up tweaking the physics engine itself to change the behavior in that case or build the vehicle model around the rigidbody and forces. I wouldn’t consider changing the physics engine for that reason alone as it involves plenty of work to integrate a separate physics engine to UE4. That is, at least unless their core vehicle model is somewhat superior to what other physics engines can offer, but I wouldn’t expect miracles. There can be other reasons to switch physics engine, for example if you can get more deterministic or more accurate results from other engine.

Only racing game I know that actually uses ODE is Assetto Corsa, and as far as I know they only use it only for collision and rigidbody physics where they handle the forces separately with their own math (which can be done on physx just as well). AC also uses a custom game engine built for that game so they needed to pick some physics engine for it (or write their own).

Quick question about the whole “Generate files and build in VS2015”

Haven’t messed with VS with UE4 yet, do I build solution? or just Build > Build > UE4 and Build > Build >CarProjectPlugin

open the solution in vs,
right click CarProjectPlugin > project only > build only CarProjectPlugin

@BoredEngineer
i think i need some help with this friction circle, im not very good at translating abstract equations into working code, im trying to follow your tank blueprint and got this far


FVector ATegCar::GetFullFrictionForce(float DeltaTime, FBodyInstance * BodyInstance, FVector Loc, int32 Index)
{
	FVector TempVel = BodyInstance->GetUnrealWorldVelocityAtPoint(Loc);
	FTransform BodyTransform = BodyInstance->GetUnrealWorldTransform();
	FVector BodyLocation = BodyTransform.GetLocation();

	FVector BodyForwardVector = BodyTransform.GetUnitAxis(EAxis::X);
	FVector BodyRightVector = BodyTransform.GetUnitAxis(EAxis::Y);
	FVector BodyUpVector = BodyTransform.GetUnitAxis(EAxis::Z);

	FVector WheelRight = BodyRightVector.RotateAngleAxis(CurrentAngle[Index], BodyUpVector);
	FVector WheelForward = BodyForwardVector.RotateAngleAxis(CurrentAngle[Index], BodyUpVector);
	
	// Calculate Mu from friction from elipse defined by MuX and MuY as radius of elipse
	float velF = FVector::DotProduct(BodyForwardVector, TempVel);

	float tmpX = MuX * velF;
	float tmpY = FMath::Sqrt(1.0f - (velF * velF)) * MuY;

	FVector2D vec2d;
	vec2d.X = tmpX;
	vec2d.Y = tmpY;
	float Mu = vec2d.Size();

	float wheelload = 1.0f;
	float MaxFrictionForce = wheelload * Mu;
	FVector FullFrictionForce = (TempVel * -1)*BodyInstance->GetBodyMass();
	
	return FullFrictionForce;
}

is that even right?
what do i do after that?, i find blueprints really hard to follow

thanks

I assume that BodyInstance is a wheel. Friction circle math looks fine. There are couple of other things which might be missing:

  1. FVector TempVel = BodyInstance->GetUnrealWorldVelocityAtPoint(Loc) is a velocity of the wheel as a static body, you need to add to it rotation of the wheel around axle. Plus you need to project relative velocity on collision surface. So that friction force lies in the surface plane, not just in XY plane of wheel.

It would be something like:


FVector TempVel = BodyInstance->GetUnrealWorldVelocityAtPoint(Loc);
float LinVelocity = WheelAngularVelocity * WheelRadius;
TempVel -= LinVelocity * vWheelForwardVector;
TempVel = ProjectVectorOnPlane(TempVel, vCollisionSurfaceNormal);

[names of the functions might not be correct, I don’t remember them]

  1. You need to normalize TempVel when taking dot product:

float velF = FVector::DotProduct(BodyForwardVector, Normalize(TempVel));

  1. Magnitude of FullFrictionForce need to be capped by MaxFrictionForce, in blueprints it’s called ClampVectorSize()

His BodyInstance is the main chassis/body in this case unless he’s changed to multi-rigidbody approach.

Actually, it’s fine if its a main chassis. Not sure why I was thinking that it have to be a wheel. As long as rotation of the wheel is take into account it should work.

thanks
yet it is the chassis
i get the ‘visual’ wheel rotation by converting linear to angular velocity. of course this doesnt allow for wheel spin.
ill have to take another look at your tank and see how you do the engine/wheel rotation.

If you already know linear velocity then just subtracting it from the velocity of the chassis at contact point will do the trick. Btw, this is not only for the wheel spin, your regular “traction force” (which technically is a friction force) depends on it.

I was looking into adding actual collision geometry for wheels. It is necessary for something like a buggy where wheels are not covered by chassis and have to provide some level of collision with environment. So yesterday I’ve tested one idea while building machine similar to this:
8f4024dec649b40027c72b1c99cd6c774935560a.jpeg

The idea is to have ski as static mesh with their own collision. Attach ski to chassis using physx constraint, but don’t use constraint’s spring, add suspension spring yourself using AddForce. Remove friction from the material of the ski - this makes them much more stable and add friction manually with AddForce by applying it directly to chassis instead of ski. This works relatively well, I still need to fiddle with settings of constraints and find the way how I can actually turn them to steer. Other than that it’s nice to get actually collision of wheel/ski with other geometry.
Couple of not nice surprises that I’ve found:

  • scene component can’t have it’s own events! I was trying to bind ComponentHit event of the ski to some custom event in corresponding suspension component (implemented as SceneComponent) and it looks you can’t do that. So you have to manually wire static mesh event to function call in SceneComponent which kind of ruins part of the abstraction that can be done otherwise (I just give name of chassis and ski component to each suspension component so aerosled blueprint doesn’t really have any code, everything is driven by components)
  • scene components can’t receive input events! So I have engine component which provides a thrust to aerosled, but unfortunately, if I want to control it’s throttle I still need to wire it up in main blueprint to receive input events.

ive played with physics wheels and constraints, overall i think it would give better results for some types of vehicles. unfortunately constraints can easily be knocked out of shape, or axes cant be properly locked, at least in my experiments.
someone posted a car example made with constraints and he managed to make it steer by setting the angular target (or whatever its called) in the constraint.

in another experiment i made a custom StaticMeshComponent for the wheels containing all the spring and tire variables.
you add as many of these components as you want, in the locations you want, in the blueprint, then the owning pawn iterates over them and sets each suspension location ect according to the static mesh location.
so you could have in your main vehicle class something that looks at all the components at begin play, wheels, ski’s, anti-roll bar and whetever. so it calculates the appropriate stuff according to the components that have been added.

you can use the angular motor of the constraint, control it by blueprint and use its force and angular target to set it to certain rotation. It gives steering in effect. It’s the all physics approach, because if the force of the angular motor is low, then steering can be blocked if there are obstacles next to the wheel (if the wheel is a static mesh with its own collision).