Finding rotation for a vehicle based on multiple line traces?

Hey all,
I’ve been working on creating a vehicle system that doesn’t rely on UE4’s physics engine, and I’ve been stumped while figuring out how to have the vehicle interact with terrain.
In short, I want to send a line trace out from each wheel of the vehicle (traveling down relative to the vehicle) and use the hit distance to rotate and move the vehicle’s body as though it is accurately moving over the terrain. I understand that this would technically work with a single trace coming from the center of the body, but it wouldn’t be the effect I’m trying to get.

I’m not sure how to combine the information from multiple traces in different locations in order to accurately translate and rotate the vehicle. Any help would be appreciated, and let me know if you need any other info or visualization from me.
Thanks in advance.

Sounds like you need to use some good old trigonometry. Now, I haven’t tried this method for this kind of use case so I cannot guarantee that it will work exactly as described. You may need to make some adjustments but I think it should put you on the right path.

This will also depend somewhat on what your capsule setup looks like, whether the pivot point of the vehicle is in the center or at the back, etc. There will probably be cases (depending on your setup it may indeed almost always be the case) where the back or front of the vehicle is clipping into the ground in which case you’d need to make sure the traces on that side go upwards instead of downwards, for example.

However, the basic principle would be to imagine two trace impact points as two corners of a right-angled triangle. This way we can use trigonometry to determine the angle of the slope.

296596-ue4-findvehiclerotationsketch.png

For this example, we’ll first use two impact points from one side of the vehicle (so either left front and left back or right front and right back).

We need to figure out the slope angle α (marked in purple in the sketch). There are handy trigonometric functions to help us do that. For example: sin(α) = opposite/hypotenuse = a/c. That means we need to know the length of a and the length of c.

To get the length of a, we need to figure out which of the trace impact points has a higher Z value and make a new vector that takes in this higher Z value but the X and Y values from the impact point with the lower Z value. This gives us the third corner of our triangle.

Now we subtract this new vector from the hit trace vector with the lower Z value and plug the result of this subtraction into a vector length node. The return value is the length of a.

To get the length of c, we merely need to subtract the two impact point locations from each other, then do the same thing as before: plug the result into a vector length node. This is the length of c.

Now we can divide the length of a by the length of c. This gives us the sine of α. To get the actual angle in degrees, we need to plug this sine value into an Asin (Degrees) node (unless you’re working with Radians, then obviously use the Radians version). The return value will be the angle of the slope.

However, this only gives us the Y rotation since we’ve only been taking the traces from one side into account. To also get the X rotation, you need to repeat this whole process using one impact point from the left and one impact point from the right side (for example left back and right back or left front and right front).

Keep in mind that you will need to make additional checks to account for cases where one or more wheels are hanging in the air. Which impact points you select to do the above calculations with will have to be informed by those checks. For example, if there’s one single impact point whose Z value is way lower than the others’ (or one trace that didn’t return a hit at all), you’d want to ignore that point. If two impact points on a diagonal (back left and front right or back right and front left) are way lower than the other two, you’d want to only work with the two highest points and only do one sine calculation (because the other two wheels would be hanging in the air).

I hope that helps give you an idea of how to get it working. (Please do test it out before accepting the answer. Like I’ve said, I haven’t actually tried it out myself, though I’m confident that it should work.)

I’ll give this method a shot when I get a chance. I’m not totally sure how I’d go about setting up variables in regards to determining which hit result has a higher Z, but it doesn’t seem like it’ll be too difficult to figure out. Thanks so much for the detailed explanation regardless!

You’ll have to break the impact point vectors (using the Break Vector node or by right clicking on the vector pin and clicking split pin) to get just the Z value, then compare all Z values with one another to find the largest value.