[ASSETS] [OPEN SOURCE] Tanks, tracks and N-wheeled vehicles

Very cool stuff. What is about performance?

I didn’t do any profiling yet. But it should be worse than using skinned mesh for tracks. I was looking at how tracks are made in Red Orchestra 2 (just by playing game and staring at tracks), they do use skinned mesh with animated UVs for the tracks and I think they mapped tracks in a clever way, such that main surface of track, sides and teeth are all on the same texture. As of now I don’t really see much benefit in using splines, unless you just can’t make those track links look good with a textures. This is an issue in my case as vehicle that I’m building is rather large - single track link is almost half a meter long. But if you want this for more classical tanks then skinned mesh would be the way to go.
The other, fancier approach is all physics, like TooManyfps did: https://forums.unrealengine.com/showthread.php?86349-All-Physics-Tank-Prototype&p=390222#post390222

Fantastic! This is exactly what I’ve been looking for in Unreal.

A few years ago (june 2013) I was working on a Tiger tank for a game in Cryengine. The test footage is still somewhere on youtube… The problem back then with n wheeled tracked vehicles in cryengine was that the maximum number of wheels was hardcoded in the engine.
Project grinded to a halt.

Last year I’ve been testing again in Unity. Problem is I’m no coder, but I found a great set of script written bij Chobi that did what i was looking for. 【Unity3D】Tank Battle Creation Kit "Physics Tank Maker" - YouTube
He helped modify some things to make it work the way I needed.

but

I moved to ue4 this year because for me it’s faster and easier to prototype with the blueprint system.
I was hoping ue would put up an example by now.

Is there any chance you could go over the basic setup, or is that to complicated to explain?
I really have no clue where to start.

I want an instanced track link system like you show… no skinned geometry with a moving UV map.
It does not have to be 100% physically accurate since I will mainly use a 1st person view inside the tank, but want it as accurate as possible when looking from the outside.
The track configuration is almost the same as the M113 (Working on a CV90 IFV), and maybe also use the same system when resurrecting the tiger.

Just let me know if you have plans to do a tutorial or want to sell the basic setup so I can get started with testing myself.

Cheers

Thank you, OldRaven!

First I would look at which features you actually want. PhysX have N-Wheeled vehicle classes and I’ve seen people successfully extending them and using in UE4. One of those classes handles specifically tanks:
https://developer.nvidia.com/sites/default/files/akamai/physx/Docs/Vehicles.html#wheeled-n-wheeled-cars-and-n-wheeled-tanks

I’ve chosen not to use PhysX as single raycheck suspension is not suitable for my setup, although it might work for M113 just fine, but M113 is just a step in direction of more complex vehicle.

I would start from setting up suspension. Some of it is explained here:

Next step is simulating friction. I didn’t managed to do it as accurate as PhysX does but I’m happy that it’s a single simulation that handles traction, slip of tracks, breaks and etc.
Simulating engine took sometime to setup but mostly because what you have is interdependent systems and small error in math in single place breaks the whole system.
Tracks are the easiest part, at least at the level where I have them right now.

Regarding tutorial or code. I’m planning to re-implement most of it in C++. Blueprints I would rather just openly share, but for this I need to find time to cleanup the project (there are some 3-rd party assets) and place it somewhere on git.
For me it’s easier to find time to explain each part step by step than do a full tutorial on all elements as each system was build in multiple iterations.

This PhysX stuff runs without tweaking on Nvidia cards only?

Most of the PhysX features run on CPU. As far as I know only some cosmetic/visual features require NVidia’s GPU.

Not sure why I didn’t uploaded latest version earlier, it was done like 4 weeks ago. Anyway you can find a link to it in the first post.
Changes in the latest version:

  • new vehicle inspired by Ripsaw tank
  • now M113 and Ripsaw are made using inheritance from a parent blueprint of A_TrackedVehicle, this gives more freedom in customization and re-usability of code
  • amount of wheels, their position, suspension settings, thread splines are all adjustable individually for each vehicle by simply overloading few functions
  • marked path in the desert to test suspension on landscape
  • adjusted mass of the rocks to behave a bit more adequately when pushed by threads

Link (added to the first post as well):
https://www.dropbox.com/s/1qz88xpz3zhyt7p/LandShips_ripsaw.rar?dl=0

The other news are regarding faith of this code. I’m planning to clean up assets and post it on git-hub, maybe it can turn into community project or at least be a useful example for education purposes.
Meanwhile I was thinking about general design of the whole thing and I see that current implementation is not rigid enough to easily build more complicated vehicles. For example, something like a half track or tracked motorcycle will require a lot of refactoring in the base class, which will lead to refactoring children blueprints which already exist. IMHO a better approach is to split vehicle into separate components - engine, suspension with tracks and chassis. But I’m not sure what is the better approach to do it. For example, blueprint script components can’t spawn meshes in constructor, which makes it complicated when you want to build a nicely animated suspension for something like Sherman tank and then re-use it in another setup.
The other option is to build parts as separate actors and attach them to chassis, this is what I’ve done for two other projects involving airplanes. It does work, but there are issues with collision and authoring of the content as attaching actors can’t be done in constructor. What other options are available?

Full source-code is on GitHub now as a public project:

Enjoy!

Wow… Great!

I know the nvidia stuff for tracked verhicles, but my problem is… I cannot (and do not) want to code. (or have the time and patience to learn)
So for now I must heavily rely on blueprints.
My math and physics is also not very good… so It’s a real struggle (read impossible) to do without having any working example whatsoever.
And although I was pretty far with my setup in Unity… that switch to UE got me back to square one.

I’m going to download your source to see if I can understand what you did there (or get it working at all).
Hopefully this is ging to finally get me moving again in UE4 to get that IFV going.

If I can be of some assistance to you , please let me know… I don’t mind trying to document a basic Blueprint setup like you implemented based on your code if that could help the community and get you working on the actual coding.
Thanx again!

diving into your source!

Peter

You have no idea how happy you made me by releasing this on github.

I took a brief look… although I’m overwhelmed and have no clue where to start yet… I’m going to see if I somehow understand how to use your example and turn it into a working version for my IFV.

Maybe you can give me a brief rundown of where and what to do when I want to implement my own Hull.

I will start by getting the basic assets ready for testing (hull, wheels, sprocket and idler).

Cheers

Peter

I’m away for the weekend and need to look at the code to remember details. Look at m133 and ripsaw blueprints. They inherit the same parent blueprint and have few overloaded functions for custom setup. Hull you can change by changing skeletal mesh of the root. You can’t edit inherited variables in a normal way, you need to open class defaults in blueprint to do it.

no problem,

I’m really busy with a project until the 18th of november so I don’t have much time right now to dive into it.
So I will dive into it as soon as I have more time for it.

Good luck with project! I’ll make a tutorial on how to get a custom setup. So if you want to help it will be a simple matter of testing it.
There are some confusing moments for sure, like for example root of the chassis is not at 0,0,0 but placed such that in 3dmax/maya tracks touch the ground - it was just easier to model like this, while all other pieces like wheels and etc. are imported with pivot at proper positions.

Sounds great!

I love to help… I will then first follow along implementing the hull portion of the CV90.
And also make a tutorial of it, or help you… whatever you want.
The CV90 has 7 road wheels, 1 idler and 1 sprocket on each side.

How is the power transferred to the ground?
In cryengine it was faked so that all the wheels contributed to driving since the track was there only for show.

I love the fact you have instanced track links and not a single piece of geometry with sliding UV , I hate that.
Choby’s unity version also has instanced track links… and you can even break the track when it get’s shot. Although that for me is not really a priority yet.

“Power transfer” is done as a part of friction simulation. Technically it’s done at points where tracks are pressed to the ground by the road wheels. In principal, any number of points at any location can be used as long as you can calculate normal force somehow. If you use points right under the road wheels then your normal force is equal to surface projection of your suspension force. For other locations you need to find a way of calculating normal force in some other way.
When we know normal force in becomes our upper total force limit in friction calculation, meaning that total friction force affecting point on track can’t be higher than normal force at this point. So when we calculate our longitude and latitude friction (assuming we have different friction coefficients) their sum have to be clamped by magnitude of normal force before we apply AddForce to our vehicle. Part of the friction is applied back to the track in the form of torque, this is what slows it done when you accelerate and speed it up in neutral (rolling down hill). So “traction” is purely a part of friction force appearing due to relative speed of track to the ground. The same math which prevents track from sliding sideways produces “traction”.

I like separate links too, unfortunately without physical simulation they don’t have too many benefits over the skinned mesh. They are just easier to model but performance wise they are worse. Red Orchestra 2 have a very nice skinned mesh implementation of tracks, it’s clever modeled and textured, creating appearance of true 3D mesh.

I was looking at the code today because of the concerns regarding how suspension works at low fps. What I’ve realized is that I didn’t finished decoupling components from parent class. There are still some inherited duplicates of components from parent class. I should deal with them first. Sorry for that, no I remember that this was the reason why I didn’t uploaded version with Ripsaw earlier.

no worries… you have at least until the 18th of november to fix it :smiley:

What would be a decent start to implement a new vehicle?

I see M113 blueprint has the ntracked ehicle bp as a parent.
So I assume that is where most (if not all) of the code is.

I’ll prepare a basic hull mesh and wheels for the CV90, from there I just need to know how to replace, reconnect and realign everything.
Als the CV90 has more road wheels then the M113, need to know how to add extra wheels…

So many questions :slight_smile:

Let’s just start with step 1.

-What should I prepare first? before moving to the next step. Think that is a good way to start documenting it if I go step by step.
And when I’m done with the first step, we move on to the next. Not everything at once, because my head will explode…

I would start with some necessary references. You could build everything without them but it’s easier to debug when you have them.
Typical list of references is following:

  1. Vehicle mass, if you can find an approximate mass for the tracks it’s even better.
  2. Clearance - this really helps to tune suspension. For example, M113 clearance is 41cm, to make sure that suspension is setup correctly I just place a box exactly 41cm high and vehicle should be able to just barely drive over it.
  3. Gear box and differential ratios. I have only manual box implemented, there is array for gear box ratios and separate variable for differential.
  4. Engine torque curve. This have to be aligned with gear box. I have some extra engine curves, for M1A1 for example but unfortunately no gear box ratios.
  5. Center of mass of real vehicle. Not extremely important as you can tune center of mass after suspension is set in place.
  6. Your tanks static mesh needs to have collision mesh.
  7. Suspension length. This one might be hard to come by but it gives a good number of how much suspension can move in total.

Updated source GitHub at github. Removed temporary suspension handles, wheels, track splines and track instanced meshes from base class. You are suppose to add them in child blueprints now and hook up into system by overriding few functions of the parent. Yesterday I’ve tried few different implementations for suspension, to make them less dependent on physics update frequency. Unfortunately non of the worked. It looks like C++ is the way to go, but I see a greater good in keeping this specific project 100% blueprint as more of a tutorial/education material.

Regarding tutorial. Now as I have a source code in front of me a bit more of the details can be mentioned:
Part I: Body, Road Wheels and Suspension
The base class of the tracked vehicles (M113 and Ripsaw as examples) is A_TrackedVehicle. This is suppose to be an abstract class which you don’t ever spawn as an actor. [it still has some content in it, primarily because refactoring is not completely finished] Base class handles all wiring of the pieces and all physics calculations. To make our own functional vehicle we need to create new blueprint as a child of A_TrackedVehicle (right click on blueprint in content folder and choose Create Child Blueprint Class) or simply duplicate M113 or Ripsaw as a starting point. They both have all necessary content and functions for fully functioning vehicle setup.

  1. As easy starting point, duplicate M113 blueprint
  2. After you’ve copied M113, replace static mesh of root component Body(Inherited). Your static mesh needs to have collision, otherwise physics won’t work properly.
  3. Set mass of the vehicle in “Physics” properties of Body(inherited).
  4. The next step is to simply move around sprocket and idler (SprocketR, SprocketL, IdlerR and IdlerL). If you want to add more of them, just duplicate existing ones and plug them in overridden function AnimateWheels.
  5. To add more wheels you need to add more suspension handles. Add more suspension handles by duplicating existing suspension handles and moving/renaming them. In M113 they are called SuspRxx and SuspLxx.
  6. Hook up new suspension handles in overridden function Constructor->RegisterSuspensionHandles.
  7. Now we need to match suspension handles to suspension settings array. Add necessary amount of elements to Performance->SuspensionSetupR and SuspensionSetupL arrays by duplicating existing records. Section “Internal” is for temporary variables, those are only modified by code, don’t bother changing them.
  8. Add extra wheels by duplicating and renaming their static mesh components, they are called Rxx and Lxx. Hook them up in overridden function AnimateWheels, where we hooked up sprockets and idlers earlier.
  9. Now you can start tuning suspension by adjusting StiffnessForce and DampingForce parameters in array of suspension structures. CollisionRadius parameter should be bigger than radius of the wheel to cover extra thickness of the threads. It’s simply radius of the wheel + thickness of the tread element.

Tracks will look off, don’t bother with them now, just disable their rendering for now. Position of your wheels might look odd, this is normal. Usually on reference photos suspension is already engaged. So at first you need to find values for suspension stiffness such that spring is half compressed and then move suspension handles so position of wheels, when tank is on the ground, matches with photo references or clearance specification.
DampingForce is responsible for how fast suspension settles down, if your vehicle wobbles too much make this value higher. StiffnessForce is the force of the spring itself the higher the value the more extended spring will be. Be careful too high value will send your vehicle flying.