Search code examples
c#unity-game-enginephysics-engine

Unity3D - Detecting Collisions on a Moving Platform


I am trying to create a moving platform that moves what is connected to it but also allow the objects that are connected to detect high-speed collisions.

I have first tried to use transform.Translate() to move the objects but this doesn't support those high-speed collisions.

Note: All script examples I have connected to the platform which is under the red cube.

public Transform connectedTo; // The red cube in the gif
private Vector3 lastPosition;

void FixedUpdate() {
    // Calculate how much the vector has changed
    Vector3 amountChanged = transform.position - lastPosition;

    // Apply the amount changed to the connected object
    connectedTo.transform.position += amountChanged;

    // Update the last position
    lastPosition = transform.position;
}

Object passing through wall


I then tried to use Rigidbody.MoveTowards(destination); instead but that was producing the same results:

public Transform connectedTo; // The red cube in the gif
private Vector3 lastPosition;

void FixedUpdate() {
    // Calculate how much the vector has changed
    Vector3 amountChanged = transform.position - lastPosition;

    // Get the point in which the object must move to
    Vector3 destination = connectedTo.transform.position + amountChanged;

    // Apply the amount changed to the connected object
    connectedTo.GetComponent<Rigidbody>().MoveTowards(destination);

    // Update the last position
    lastPosition = transform.position;
}

This is my Rigidbody setup on my red cube:

The Red Cube's components

The wall and platform both have a standard box collider.

I have read that to detect these high-speed collisions Continuous collision detection must be active AND the movement must be done using forces. Unity Documentation & High Speed Collision Video

The issue with forces is I don't know how to move the connected object as was done in the previous scripts using translation.

// This barely moves the object connected to the platform
connectedTo.GetComponent<Rigidbody>().AddForce(amountChanged, ForceMode.Impulse); 

Using a fixed joint will not allow the connected object to move independently.


TL;DR:

How do I create a moving platform that will allow things on top to move with it while also being able to move independently AND detect collisions at high speeds?


Solution

  • Translation allows "teleporting" though the wall as you observed. If you are fast enough, or FPS are low enough, it will pass though the wall.

    Options:

    1. Secure the translation with a Raycast. From old to new position.
    2. Secure the translation with a Spherecast or Boxcast
    3. Apply the velocity of the platform + playerinput (so you can still walk) to the player.

    Also check out the Collision Detection settings:

    enter image description here

    But please note, that moving the object in scene using your mouse will not set the velocity of the rigidbody. So to test if it's not passing through the wall, you need to ping-pong your platform using physics.