Endless runner ground collision issue.

Hello,

I am working on an endless runner game, but there’s an issue with the player moving forward over instantiated road prefabs. sometimes (not always), when the player has “entered” a new instance of the prefab, he bounces up in the air. It seems to occur more frequently when the speed is relatively high. See the video below.

Obviously, I am using a Rigidbody and I am handling the forward movement with

if (rb.velocity.magnitude < playerSettings.maxSpeed)
        {
            rb.AddForce(0f, 0f, playerSettings.forwardMoveSpeed);
        }

The transforms of the prefabs are exactly the same (only goes for the x and y-axis, z-axis is different for each instance, of course) , and to make things easier and less prone to bugs, i gave the entire prefab (which consists of 10 smaller “road” prefabs) a BoxCollider. It also seems to happen more frequently when I’m moving sidewards, which happens with these lines:

private void movePlayerSideWays()
    {
        float horizontalinput = Input.GetAxis("Horizontal");
        Vector3 movementvector = new Vector3(horizontalinput * playerSettings.horizontalMoveSpeed, 0f, 0f);

        rb.AddForce(movementvector);
}

.

The player has a PhysicsMaterial with everything set to 0. I’ve tried multiple asset packs, as well as a simple cube, scaled up 10x, to see if it was the asset pack to blame or the code/collider of my player. It seems to be on my end, not the asset pack’s one. I found a tutorial with a comment, describing a similar issue, on which the uploader responded “Tick all rotation constraints”. That was already the case for me, so it didn’t have any effect. Any ideas?

The solution really depends on your final goal.
On the simplest side, if you’re not using gravity, you wouldn’t even need the ground.
Or with gravity if the player isn’t moving, does the ground need to move? We could just perceive the ground as moving. You could remove the collider from the moving road prefab and create an invisible ground that doesn’t move.
I don’t see in your code where the endless road is coming from, instantiating and destroying clones or teleporting the road behind the camera out to in the distance.
What collider is on the motorcycle? Wheel colliders?

Hi, thank you for your reply :slight_smile:

I am planning to use gravity, or mechanics related to the rigidbody for which gravity is required (bombs, bounce pads etc), so that’s not really an option.

As for the ground moving illusion, I was thinking about a shader (although that would be the first one for me) that moves the texture, while the ground itself has the same velocity as the player, but I imagine that as a whole other level, and wanted to explore other (easier) solutions first.

In theory, I could just create a immensely long plane/collider but that counters everything I’ve learned about efficiency and good programming so far. The tile generation code instantiates prefabs when needed and removes them from the list when no longer needed.
It’s the following code:

#region Variables

    [SerializeField] private GameObject[] tilePrefabs;
    [SerializeField] private List<GameObject> activeTiles;

    [SerializeField] private GameObject tileParent;

    private Transform player = null;
    private float spawnZ = 0.0f;
    [SerializeField] private float tileLength = 5.0f;
    [SerializeField] private int amountOfTilesOnScreen = 50;

    private float safeZone = 320.0f;

    #endregion

    private void Start()
    {
        player = GameObject.FindGameObjectWithTag("Player").transform;

        for (int currentTiles = 0; currentTiles < amountOfTilesOnScreen; currentTiles++)
        {
            spawnTile();
        }
    }

    private void Update()
    {
        if (player.transform.position.z - safeZone > (spawnZ - amountOfTilesOnScreen * tileLength))
        {
            spawnTile();
            deleteTile();
        }
    }

    private void spawnTile(int prefabIndex = -1)
    {
        GameObject tileInstance;
        tileInstance = Instantiate(tilePrefabs[0]) as GameObject;
        tileInstance.transform.SetParent(tileParent.transform);
        tileInstance.transform.position = Vector3.forward * spawnZ;
        spawnZ += tileLength;

        activeTiles.Add(tileInstance);
    }

    private void deleteTile()
    {
        Destroy(activeTiles[0]);
        activeTiles.RemoveAt(0);
    }

It works as intended, so I don’t see a problem there.

Sidenote, I could also just reposition them on the z-axis but I don’t think that would fix the collision problem. On the motorcycle, I decided to keep everything as simple as possible so I tried it with multiple colliders (first with a boxCollider, but my thought was: since the boxCollider has “solid edges”, maybe that’s the cause of the buggy collision. When I tried a CapsuleCollider, I saw that wasn’t the case since it kept happening.

I’ve just now tried WheelColliders on the wheels as you mentioned (which had a very strange effect). When the mass was set to 1 for each wheel, the bike would travel multiple thousands of units per second downwards. All other values where the default ones.

I think part of my suggestion was not written clearly.
What I meant was that the road doesn’t have to be the same object as the motorcycle’s “ground”. The motorcycle could rest on an invisible cube or plane with zero forward velocity, and the road prefabs creating the illusion of movement but not interacting with the road prefab.
There is a Unity Learn Course going on right now, it is free and if it is the same as it was in the spring then it would be perfect for what you are doing. It involves and endless runner and a driving part with road prefabs. If it isn’t the same, then the one this spring is still there just not live. Here is a link to the endless runner from the spring.
This is current live course where you can ask questions in chat.

Ah, I see. I think the way you’re suggesting should indeed work, when I have the chance I’ll check out the links and try out your (and Unity’s) solution. Thanks for the help!