- Home /
Preventing characters falling through world when altering terrain at runtime
Is there any way I can detect when a run-time terrain edit causes a player to fall through the world, and bump the player back above ground?
I'm allowing players to raise and lower the heightmap of the terrain in game, whilst using a first person camera. This means they can potentially raise the terrain below their feet, which currently causes them to fall through the world unless they jump first.
I was considering keeping a global list of all players, and after every terrain edit, for every player do a raycast from the sky above him, vertically down to the terrain, then comparing the hit Y position to the players Y position. However I'm unsure if this is scalable if I want to in future check for other objects such as enemies, trees, objects on the ground, etc.
I have read about physics spheres, but the sphere would have to be pretty huge to account for the case of one very low point and another very high point next to it, then the player on the slope between them.
What's the best method of detecting and bumping players back up?
Answer by Waz · Aug 14, 2011 at 12:19 AM
You could use TerrainData.GetInterpolatedHeight to find new position and move any objects that are below their corresponding position. That will be more efficient than raycasting.
It seems that because the player collision is a capsule, if i snap the player to the side of a very steep hill using the Y co-ordinate of the terrain directly underneath (or above) him, the capsule will still overlap the side of the slope and the player will fall through.
Does this sound accurate? I'd be interested in knowing exactly what part of the character can overlap without falling through.
Will you always know where a given modification will occur? $$anonymous$$aybe as part of the terrain modifying script, you can find all the players in the affected reigon and move them in the same step. As far as I know, capsule colliders are fairly resilient when it comes to slight overlap- if they are less than half of their total width through another collider they will get forcibly ejected in the next phyisics step
So, no, I don't think it'd be a problem. Have you tried giving the players affected a small upward force to bump them over the modified terrain? It'd make a bit of sense, as well- seeing as a big hill just appeared under their feet!
That's exactly what i'm currently doing - calculating a radius around every modification, and bumping every player in the radius up. In fact what I'm doing is checking the height of the terrain at the player position, after the modification, then bumping the player to that position plus a little bit more for safety.
However, that safety number is a little higher than I'd like (0.2m), anything lower and occasionally players fall through the world..
$$anonymous$$aybe I misunderstand what GetInterpolatedHeight returns, do you need to scale it depending on the height resolution?
Here's the code I'm using
var playerTerrainPosX = (playerFeet.position.x - terrain2.transform.position.x) / terrain2.terrainData.size.x; // assumes terrain is at origin 0,0
var playerTerrainPosZ = (playerFeet.position.z - terrain2.transform.position.z) / terrain2.terrainData.size.z; // assumes terrain is at origin 0,0
var terrainHeight = terrain2.terrainData.GetInterpolatedHeight(playerTerrainPosX , playerTerrainPosZ) + 1.05;
if (playerFeet.position.y < (terrainHeight - 0.01) )
{
Debug.Log("Player is below terrain, bumping up. Player was at height : " + playerFeet.position.y + ". Terrain was at height: "+terrainHeight+". Bumping to: "+ (terrainHeight + 0.2));
playerFeet.position.y = terrainHeight + 0.2;
}
Do your characters use rigidbodies? If they do, ins$$anonymous$$d of just manually assigning the bump, do that and then use AddForce to make the player jump in the air a bit. This way it makes sure the player is entirely out of the terrain, and it lets normal collision take over when the player lands.