Building a suspension for the Tank

@RyanPalmer: thanks a lot mate.

Major Update

This is what i got to work this weekend:

Looks abit similar to what you have seen before, but instead of ugly replicating Meshcode, i have managed to make my first C++ procedural Pointer-Array based Meshgeneration, Animation and Positioning method.
In addtion, the spline is now a real loop. Sounds easy, but gave me a hard time to implement correctly with hours of viually debugging the whole method. The Bug-Solution was in one of the last lines of code, a very very nasty typo error interferring with the second spline. But at least, i solved it, one more bug is wiped out, learned a lot about splines and had some fun too.

So now, with a second spline, i spawn 96 tracktiles like nothing, in addition its now about 350 lines less code, all refactured and pretty readable.

For me, this is a major achievment in coding with UE4.

Just for fun: A 100 tracktile whirling centipede whatever…lol

@Ben: I found a major bug in the Tankmovment for AI Tanks. I am not sure if it was mentioned before. I will make an extra thread/post for it the next days, sorry for the delay, but i need to get some sleep, work starts early tomorrow.

5 Likes

Solid stuff! I shall have to investigate these splines…

Thanks L-Tec, for the initial how to you posted a couple weeks ago.

Was actually kinda hard to figure out… but wouldn’t have figured it out at all without what you posted there!

Few things for anyone else trying to implement a basic physics constraint style suspension following along with L-Tec’s pointers:

Don’t parent the wheels to the constraints. Constraints and items that they’re constraining on should be on the same level.

Set the components to constrain to via component name (drop down box, then fill out the text box… no selection menu, no drag and drop - just click on the components, F2 to rename, ctrl+c to copy and ctrl+v into the constrain text box).

The wheel object should only be scaled uniformly. Scaling it non-uniformingly creates a strange bug where it disregards the collision mesh… i.e. you can’t use a sphere and scale it into a disc. Unfortunately.

Most importantly, the wheels need to be set as physics enabled. Counter intuitive if you haven’t been told - because doing it with non constrained objects will cause those objects to fly off from the tank! In retrospect, that makes total sense, because those objects aren’t constrained.

The other bits can be played with to your hearts content, because it’ll actually work… if it doesn’t, then tweaking those numbers won’t do diddly squat! :stuck_out_tongue:

Update

Complete spline track working now.
Everything you see is spawned procedural, Number of Wheels, Number and width of tracktiles to use per side, Position of Front and Rear Wheel/Sprocket is settable, suspension is settable with almost all values via Blueprint.

Next to come… maybe traction and friction or other stuff not sure right now.
I will keep you informed.

@Zaptruder: Cool that i gave you an initial hint how to start, looking forward to your creations

2 Likes

Visual Debugging the ranged Collision method of the track:

2 Likes

I’ve uploaded a new demo! Features the bouncy suspension from your first post - works reasonably well, although I see from your posts, I have a significant journey ahead of me to implement moveable animated tracks. Give it a shot, let me know what you think :slight_smile:

Your track updates are looking pretty mega btw. Glad to see that I wasn’t the only person taking the line trace approach to determining collision.

Awesome work ! Though you should set the specular entry of your landscape material to zero

@Guillaume_Feraud:
Thanks for the huint with the specular setting, will do some artwork soon to make landscape and textures look better.

Update

Even though the tracks work good on ladscape, they have a clipping issue with edged object.

So i reworked one side of the suspension, obviously the right one:

Old/New comparison:

Was a hell of work…a major advance imho.
Need to add the wheels again…I will keep you updated.

4 Likes

Awesome work, inspiring

@sampattuzzi have a reac

How did you implement the sag in the track? Is it hard coded or does it depend on how much the wheels are stretching it?

@sampattuzzi:

The sag, right now it is still a bit faked.

I do know the total length of the chain each time i make it visual and the final goal is to have a static length all the time, what i do not have archieved right now, quite mad maths for me.
This will visually efffect the UPPER part of the track, it will be held up with suppport castors one day and sag between them depending on the state of the suspension and the resulting overalll track length of the lower part.

The sag you see right now is calculated locally by the end of contact of the track to an object and distance to the next contact of the track after the spacing.
I have a hardcoded spline shaped like a wave, which i scale by the distance of the spacing and then use it for the drop-off calculation of the single track tiles.

Curenttly i try to reimplment the lower castors again, which gives me a hard time calculating their position against a wave form track in one cycle instead of iterating it.
I just do not like to iterate heavy used stuff, but use clean and straigth maths instead, in most cases this is way better for performance imho and makes the code easy to read and understand.

So if someone has a cool and easy formular for a 2D Vector calculation, how i can get the position of a circle with a set radius over a spline while the imaginary Y-Axis(it is the upvector of the tank but just think of it as imaginery Y-Axis, we are looking at it in 2D here) is fixed in its X-Position and the Circle having a limited amount of Y-Axis travel using the spline function to calculate the nearest spline point from a given location in world space…just let me know. It gives me a hard time right now.

1 Like

UPDATE

Lower track castors added again.

Finding the right position for the wheel in relation to the spline gave
me quite a hard time, took me 2 attempts to find the right and
cpu-friendly maths to do so.

Result is quite ok imho:

8 Likes

Looks amazing! To be technically accurate. The 7-72 model should have 3 return rollers supporting the top of the track.

That’s crazy impressive!

I’ve had a coding break since 20th July as summer holidays and kids :smiley:
I’m just coming to the end of the BattleTank section and come accross this post.
This is just “Wow” I dont even know where to begin to get anywhere close to this! But try i must as this is needed for any development i would want to make.

Thanks for sharing and showing it can be done with a little determination and hard work.
Great job mate and wish me luck! (Finishing off part 2 here i come!)

whoa that is some really impressive stuff. Great job!

This is just too incredible to keep in the BattleTank section so I have moved it to the showcase for all students to see what is possible when you set your mind to it.

2 Likes

I would be nice, to have a section for battle-tank where @ben or others leave code snippets of things like this, I’m working on something much less complicated. But what I’m envisioning is “Exercises” without solutions, where Ben gives you some hints on what would work, and the students try and figure it out, and if you post a solution that works, you get access to all the other people’s answers.

Personally, I’m trying to get a UV Panner to work, but my current Issue that I’m working around is, that everytime I set the panner’s U or V value for the track It resets the Panner’s position, and then starts panning. So I’m trying to ->Modulo<- (%) the values, so I get a remainder for a 0-1 UV space, which isn’t easy since Modulo is meant to run with Int’s not floats, so I found myself multiplying and dividing my solution, but I think I’m hitting rounding errors.

In the UTankTrack class I’m setting this in the constructor which makes a material instance, and allows me access to any material parameters :

MaterialInstance = UMaterialInstanceDynamic::Create(GetStaticMesh()->GetMaterial(0), this);	
this->SetMaterial(0, MaterialInstance);

And then I have a new Method Called UpdateMaterialPanner, that goes like this :

void UTankTrack::UpdateMaterialPanner(UMaterialInstanceDynamic* TrackMat)
{
	if (!TrackMat) { return; }
	float TrackSpeed = 0;
	
	FVector Velocity = TankRoot->GetComponentVelocity();
	float Speed = (Velocity.X) / GetWorld()->DeltaTimeSeconds;
        TrackMat->SetVectorParameterValue(FName(TEXT("TrackSpeedUV")), FVector(0.0, Speed , 0.0));
}

Which the last line is the thing that modifies the UV’s Position, but I’m having an issue with the Velocity.X values I’m getting and dividing them by the track length to get the tracks moving. Just an alternative to actually moving the tracks, which I know can be Performance Heavy, and as a VR Developer, I’m used to making sacrifices to keep things “rolling” (Pun) at 60+FPS. Preferably 90.

Hoooly…!!! I was just thinking about a custom track for my own project aswell. You sir are higly inspiring! Thanks for sharing your progress, you gave me a bunch of directions how to do it.

Privacy & Terms