I'm programming a simple physics system for vehicles in Unity and I'm trying to figure out how to calculate the average slope based on four points in order to apply the gravitational acceleration. I can get the terrain height at the vehicle wheels positions like this:
Terrain.activeTerrain.SampleHeight(wheel.position);
How can I calculate the average terrain slope based on those four points? I thought about calculating direction vectors between different points, but I'm not sure how to combine them into a single slope vector.
(Assuming that all 4 wheels are always coplanar) I think you could take any 3 wheels, take the height sample
var wheels = new Vector3[3]{ wheel1.transform.position, wheel2.transform.position, wheel3.transform.position };
for(var i = 0; i < wheels.Length; i++)
{
var w = wheels[i];
w.y = Terrain.activeTerrain.SampleHeight(w)
wheels[i]= w;
}
and from that resulting 3 points generate a plane
var plane = new Plane(wheels[0], wheels[1], wheels[2]);
Now you can take any of these points and take a vector in straight up direction.
var upPoint = wheels[0] + Vector3.up;
Then you can map that vector onto the plane using closest point on plane.
var planePoint = plane.ClosestPointOnPlane(upPoint);
As a last step normalize the vector between that mapped point and your start wheel point and you should have the direction of the slope + the Y component tells you how steep it is
var planeVector = wheels[0] - planePoint;
var direction = planeVector.normalized;
Debug.Log($"Slope direction is {direction} with a steepness factor of {direction.y} or also {-planeVector.magnitude}");
where both planeVector.magnitude
and direction.y
should be moving between 0
(completely horizontal surface) and -1
(completely vertical surface)
Something like that I guess ^^