Fast moving object collision detection is unreliable

I have a bullet that moves really fast in a boomerang pattern. Ive enabled continuous dynamic detection for both the bullet and the target, but still the OnTriggerEnter only triggers like 80% of the time, what else can I change to make sure its 100%?

9263502--1296294--upload_2023-8-31_14-37-25.png

IEnumerator InitialMovement()
    {
        float elapsedTime = 0.0f;

        while (elapsedTime < speed)
        {
            elapsedTime += Time.deltaTime;

            float t = Mathf.Clamp01(elapsedTime / speed);
            float curveValue = initialSpeed.Evaluate(t);

            rb.MovePosition(Vector3.Lerp(start, end, curveValue));

            yield return null;
        }

        StartCoroutine(ReturnMovement());
    }

    IEnumerator ReturnMovement()
    {
        float elapsedTime = 0.0f;

        while (elapsedTime < speed)
        {
            elapsedTime += Time.deltaTime;

            float t = Mathf.Clamp01(elapsedTime / speed);
            float curveValue = returnSpeed.Evaluate(t);

            rb.MovePosition(Vector3.Lerp(end, start, curveValue));

            yield return null;
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.TryGetComponent(out Health health))
        {
            health.TakeDamage(10, gameObject);
        }
    }

I would say it’s because you are moving the rigidbody in Update() (coroutines) rather than in FixedUpdate().

Physics by default runs at a fixed timestep (0.02s == 50 Hz - every time when FixedUpdate() gets called) whereas Update() runs once per rendered frame, so 60 Hz or even way more on a fast monitor (120/240 Hz) or possibly a lot more often with Vsync disabled (300+ Hz).

That means between two physics intervals your object may have both entered and exited the trigger collider. Rigidbody properties should only be modified in FixedUpdate().

Possibly related (but probably not): Unity - Manual: Continuous collision detection (CCD)

1 Like