Correctly moving modular terrain in endless runner with moving terrain & fixed player

I’ve been trying to fix an issue I’ve been having with a little endless runner type of game I’m working on for days now.

I decided to go the fixed player and moving terrain route, as I’ve read that letting a transform value get too big can result in loss of precision, but I can’t implement this without having my test player, a cube, “trip” at the seam between two pieces of terrain when they move.

Each piece of terrain is a prefab made like this:

  • Street (contains the Rigidbody, with IsKinematic propety True): this is an empty object containig the:

  • Road (contains MeshRenderer and BoxCollider) - this is where the player “runs”

  • leftSidewalk and rightSidewalk (contains MeshRenderer and BoxCollider)

The terrain spawning script uses the Meshrenderer.bounds.size of the Road object to compute the correct transform to instantiate the following terrain piece. This seems to be correctly working to me because if I test by stopping the terrain and moving the player the “tripping” does not happen.

The issue arises when i actually move all the terrain pieces. In all my attempts I cycle through the array of terrain objects using a foreach statement and apply the same exact movement. I tried applying the movement in different ways:

  • Moving the transform directly:
    movement is smooth and tripping does not happen. unfortunately, any obstacle i place on the terrain does not move with it, I think because by moving this way the terrain is not taken into consideration when computing friction.

  • Moving the terrain using Rigidbody.MovePosition in Update (using Time.DeltaTime):
    this does not cause tripping, but it stutters often especially when i also move the player.

  • Moving the terrain using Rigidbody.MovePosition in FixedUpdate:
    this causes the player cube to trip (and roll) at each conjunction between two pieces of terrain. visually, I can’t see any gap. I also tried turning IsKinematic to false but in this case the terrain pieces start drifting apart after a few seconds. Also, as i don’t want anything to influence the road, I don’t think this would be good, right?

The only solution I see for now would be to instantiate each terrain object under a parent empty object and move that one, but at that point it would be equivalent to moving the player as far as Transform values go.

I’m at my wits end, and looking for similar projects online I could not find people with the same issue as me.I hope i gave enough info without rabling too much… does anyone have any clue on how to solve this?

If you’re using RigidBodies then the optimal method is to use MovePosition in FixedUpdate, and also ensure that Rigidbody interpolation is set to “interpolate”.

As for the tripping, that’s likely because there is an actual collision with the edge of your terrain pieces. Because the collision is with an edge (or two edges) the normal(s) don’t point directly away from the terrain, they point out from the edge, resulting in a depenetration force in an unexpected direction.

So my first question is, what is the ground collider actually used for? I’d need to know more about your game design and implementation, but personally I’d be tempted to not use Character Controller / Rigidbody vs. Terrain collisions for this, especially since you’re using non-realistic physics in the first place (as the character is staying in-place). I’d think about using custom ray / sphere cast collisions. Another approach is to set the player to not collide with the ground, and provide a separate ground collider which stays in place with the player. That will only work if the ground is flat, though.

Thank you for your answer!

My idea was making the runner a physics-based one. Think like a simpler version of humans fall flat. You say the physics is non-realistic, but isn’t this just a change of reference? Technically the collision would be the same whether the player hits an obstacle or an obstacle hits the player as long as the combined speeds are the same.
Still, I’m barely an amateur so I could very well be wrong.

The terrain collider is also used so that, when i spawn obstacles, they move along with the street thanks to friction (this is the main issue of why I couln’t move the terrain manipulating the transform directly, as friction doesn’t appear to be included in calculations that way.)

I really like the separate ground collider for the player idea! I’ll give it a shot.
As well as the custom cast collisions, maybe i can use mostly animations and only activate a "ragdoll’ effect once a collision takes place.