- Home /
Smooth camera height adjustment based on terrain
Hello, I have written the following code for an RTS-style camera, which works "well", but not exactly how I want.
function LateUpdate()
{
var currentHeight = Terrain.activeTerrain.SampleHeight(transform.position);
transform.position.y = currentHeight + 90;
}
Basically, it constantly detects the height of the terrain under the camera and keeps it 90 units above it. But it adjusts the height too quickly, thus if the terrain is jittery, the camera will feel jittery (e.g. it's only as smooth as the terrain is).
Below is an illustration of what I would like, but I'm not sure how to do it. Any thoughts?
This has been answered many times before. Search for 1000's of answer on Lerp.
I have tried both of these, and neither of them actually smooths/dampens the camera path. As soon as the camera passes over terrain, it basically instantly adjusts to it.
This seems to work fine :
var currentHeight = Terrain.activeTerrain.SampleHeight( transform.position );
transform.position.y = $$anonymous$$athf.Lerp( transform.position.y, currentHeight + 90.0, 0.1 );
You could change 0.1 to a lower value for a slower lerp.
But that's not how Lerp works. According to the docs:
When t = 0 returns from. When t = 1 return to. When t = 0.5 returns the average of a and b.
t cannot be a fixed number, it needs to vary, else Lerp never actually moves the value from your starting point to your target, it just stays a certain percentage of the way through.
That's what I tried initially, and it just kept the camera at some height between my current height, and my target - it never actually animated it.
Actually, the value can be fixed as long as the first parameter of the Lerp() is updated each frame. The results are an eased movement rather than a linear one. Think about it this way, with a value of .1, each frame the Lerp() will move 10% of the way from the current value to the goal value. As the distance shrinks, the 10% represents less an less distance. If the goal is moved, then the 10% will again increase.
Answer by betaFlux · May 24, 2019 at 03:23 PM
It has been a while, but a legit question deserves an answer. May be it'll be helpful for future problem solvers. I had the same problem and just used Mathf.Lerp to set the new height.
Vector3 camPos = transform.position;
float groundLevel = Terrain.activeTerrain.SampleHeight(camPos);
camPos.y = Mathf.Lerp(camPos.y, groundLevel + 90, Time.deltaTime * responsiveness); // 10 responsiveness results in a good not too lazy movement
transform.position = camPos;