(C#) Collision Ceases when object changes rotation direction

Hi Unity Community!

I’m trying to implement a simple system (in a semi-retro platformer) where the player runs across a bridge that rotates around it’s Z axis depending on which side he’s on – basically lever. I found that the simplest way to do this was via Trigger colliders. I have a cube with a box collider, and two children empty objects with the trigger box colliders on each side of the bridge. When the player enters the trigger, rotate – when he leaves, rotate back to 0.

However, if the player leaves either Trigger (meaning he’s at the center of the bridge) and stops (there shouldn’t be any reason for him to stop, but still…) and the bridge is rotating back to 0, the box collider on the cube stops working and the player falls through the bridge.

Also, I’ve found that this disappearing collider is temporary – maybe only for one frame. Because it works perfectly find when the player climbs back onto it.

The fact that this doesn’t happen each time (just most times) leads me to believe that this is an honest bug on the physics implementation. Here’s the code:

public class WobblyPlatform : MonoBehaviour {

    public float rotationSpeed = 3.0f;                                                                      // This speed affects the direction of the rotation as well

    private float length;                                                                                   // This isn't being used right now
    private Transform platform;                                                                             // This isn't being used right now
    private Vector2 negTorquePoint;                                                                         // This isn't being used right now
    private Vector2 noTorquePoint;                                                                          // This isn't being used right now
    private Vector2 posTorquePoint;                                                                         // This isn't being used right now
    private bool onPlatform;                                                                                // Flag for when player stands on the platform

    // Use this for initialization
    void Start()
    {
        length = transform.localScale.x;
        // Because this script is inside a child empty object, we need to get the parent object to change its rotation
        platform = transform.parent;
        negTorquePoint = new Vector2(0, length * 0.39f);
        noTorquePoint = new Vector2(length * 0.4f, length * 0.59f);
        posTorquePoint = new Vector2(length * 0.6f, length);
    }

    // Update is called once per frame
    void Update()
    {
        // If the player is inside this Trigger than rotate the platform
        if (onPlatform)
        {
            platform.Rotate(Vector3.forward * rotationSpeed * Time.deltaTime);
        }
        else
        {
            // If the player is outside of this Trigger and the rotation is negative 
            if (rotationSpeed < 0)
            {
                // rotation direction determines this condition
                if (transform.eulerAngles.z < 180)
                {
                    platform.Rotate(Vector3.forward * rotationSpeed * -1 * Time.deltaTime);
                }
            }
            else
            {
                // rotation direction determines this condition
                if (transform.eulerAngles.z > 180)
                {
                    platform.Rotate(Vector3.forward * rotationSpeed * -1 * Time.deltaTime);
                }
            }
            
        }
    }

    void OnTriggerEnter(Collider other)
    {

    }

    void OnTriggerStay(Collider other)
    {
        print("on wobbly platform");
        onPlatform = true;

    }

    void OnTriggerExit(Collider other)
    {
        print("off of wobbly platform");
        onPlatform = false;
    }
}

Anyone know of a workaround? :slight_smile:

I think it’s likely caused by two things. You’re manipulating the platform by its transform, and you’re doing it during Update() instead of FixedUpdate(). This will surely cause colliders to behave incorrectly when it comes to interacting physically with other colliders and rigidbodies.

Instead of using transform.rotate on the platform, try this. Give the platform a kinematic rigidbody component, then use Rigidbody.MoveRotation during FixedUpdate().

I hope it helps.

Thanks for your input chrisso!

I tried your suggestion, but my player is still falling through, with the added issue that the bridge is now jittery when it’s not rotating. I’m going to keep it in FixedUpdate() since that’s probably a good idea, but it looks like the rigidbody isn’t making much of a difference.