Why is AddExplosiveForce is breaking my Coroutine?

AddExplosiveForce was causing my Coroutine to exit early so I moved it to fixed update with the same results. The physics works better now where it was really weak before but after exploding my code skips the end of the Coroutine where I delete the object.

    IEnumerator Explode()
    {
        float timer = 0;

        while(!timeExplodeCancel && timer < timeExplode)
        {
            timer += Time.deltaTime;
            yield return null;
        }

        Instantiate(effectBurn, this.transform.position, Quaternion.identity);
        Instantiate(effectExplosion, this.transform.position, Quaternion.identity);

        explodeBoo = true;

        while(!fixedUpdateDone)
        {
            yield return new WaitForFixedUpdate();
        }

        Destroy(this.gameObject);

        yield return null;
    }

    private void FixedUpdate()
    {
        if(explodeBoo)
        {
            explodeBoo = false;

            Collider[] hitColliders = Physics.OverlapSphere(this.transform.position,
                                                explosionRadius,
                                                layerMask,
                                                QueryTriggerInteraction.Ignore);

            foreach (var hitCollider in hitColliders)
            {
                if (hitCollider.GetComponent<EnemyHealth>())
                {
                    hitCollider.GetComponent<EnemyHealth>().Damage(damage);
                }
                else if (hitCollider.GetComponent<EnemyHealthRelay>())
                {
                    hitCollider.GetComponent<EnemyHealthRelay>().Damage(damage);
                }

                hitCollider.gameObject.GetComponent<Rigidbody>().AddExplosionForce(explosiveForce,
                                                                                   this.transform.position,
                                                                                   explosionRadius,
                                                                                   3.0f);
            }

            fixedUpdateDone = true;
        }
    }

Have you actually monitored your two booleans? Are both set to true after the explosion? There should be no need to do this bool acrobatics as WaitForFixedUpdate does put you into FixedUpdate anyways. So the code after that yield would run in the next fixed update cycle anyways. If a coroutine does not complete there are only a couple of possible reasons:

  • First if there’s an exception inside the coroutine, of course it would terminate. Though you should see an error in the console about that. You do not have any errors in your console, right?
  • The other most common reason is that the coroutine is terminated either explicitly or implicitly.

The last point needs some explanation. First of all you should figure out on which object your coroutine is running. Note it doesn’t matter in which object the coroutine is defined but only on which MonoBehaviour you call StartCoroutine on. The instance with the StartCoroutine call actually houses the coroutine. If the coroutine runs on an object that is destroyed or deactivated, the coroutine would be terminated.

We don’t know from where you call StartCoroutine to start your coroutine. Though if you don’t have errors in your console, you probably run the coroutine on an object that is deactivated or destroyed. A common solution is to run such coroutines on a persistent MonoBehaviour. If you have any kind of manager / singleton that is not destroyed, you can simply do

YourManagerSingleton.Instance.StartCoroutine(Explode());

Of course this assumes a singleton with an “Instance” property. When doing this, the coroutine would be run by the singleton instance and should finish properly, even when the object that made that call is destroyed or deactivated.

ps:
About the first case. If you actually get an error (if any, probably a null reference exception) it may be related to the fact that you call those “Damage” functions on your enemy instance and after that you try to add an explosion force. We don’t know what that Damage function does exactly, but I guess if the health of that enemy is 0 it may destroy the enemy? That means after your Damage function is called, the enemy is dead / destroyed, so you should not try to reach out to it’s rigidbody. You can try to move the AddExlposionForce line above the Damage calls.