Recursive method causes an OutOfMemory error

If a GameObject in my game has a special ability it triggers it, but I want all the special GameObjects that this GameObject affects to also trigger their abilities, for example if a bomb hits some objects, if these objects are also bombs, trigger them too. I though this would be easy by calling the method that handles all the special abilities recursively, but it wasn’t. Basically what happened is a chain reaction of bullcrap that caused Unity to show an OurOfMemory error. Also makes my PC freeze completely while politely turning all the screens off.

The question is, how can I make it so it triggers all the affected cubes’ special abilities, without everything going nuts?

Code:

         //Triggers the cube's special ability, if it has any
        private void TriggerSpecialCubeAbility(GameObject specialCube) {
            switch (specialCube.tag) {

                //Destroy all cubes in a radius from the special cube
                case "Bomb":
                    TriggerBombAbility(specialCube);
                    break;

                //Destroy all cubes of the same color as the special cube
                case "Lighting":
                    TriggerLightingAbility(specialCube);
                    break;
                default:
                    break;
            }
        }

        private void TriggerBombAbility(GameObject specialCube) {
            var nearbyColliders = Physics2D.OverlapCircleAll(specialCube.transform.position, explosionRadius);
            Instantiate(particles[0], specialCube.transform.position, specialCube.transform.rotation);
            Instantiate(particles[1], specialCube.transform.position, specialCube.transform.rotation);

            foreach (var collider in nearbyColliders) {
                if (collider.tag == "Indestructible")
                    continue;

                var affectedCube = collider.gameObject;
                TriggerSpecialCubeAbility(affectedCube);
                Destroy(affectedCube);
            }

            destroySelectedCubes = true;
        }

so… you trigger a bomb, get all nearby bombs, trigger them, which gets all nearby bombs, which triggers them, which gets all nearby bombs, which triggers them, which gets all nearby bombs, which triggers them, which gets all nearby bombs…

see the problem?

After a bomb has exploded, flag it as exploded. Then if triggered again, don’t explode if already exploded.

The gameobject disappears after it explodes so I don’t need to flag anything, it’s gone

I think you’re approaching this the wrong way (but maybe not).

It looks like you are having the main bomb handle the explosions of the other bombs. The bomb should handle their own explosions.

In a way like this (untested):

using UnityEngine;

public class Explode : MonoBehaviour{

    [SerializeField]
    float explosionRadius = 5f;

    private bool explode = false;

    void FixedUpdate(){
        if (explode) {
            var nearbyColliders = Physics2D.OverlapCircleAll(transform.position, explosionRadius);
            for (var i = 0; i < nearbyColliders.Length; i++) {
                nearbyColliders[i].SendMessage("TriggerAbility", SendMessageOptions.DontRequireReceiver);
            }
            Destroy(gameObject);
        }
    }

    void TriggerAbility(){
        switch(gameObject.tag){
            case "Bomb":
                explode = true;
                break;
            case "Lighting":
                explode = true;
                break;
        }
    }

}

The way it works is this. I select 4 gameobjects and if one or more are bombs (lighting ability doesn’t work for now so don’t count that in, and I haven’t added more as of yet) they explode causing all the gameobjects near them to destroy themselves. If some of these objects are also bombs, they should trigger too, and so on and so forth.

  1. note, you collect all colliders BEFORE destroying

  2. just because you called destroy, doesn’t mean it won’t be picked up in a physics sweep. The physics doesn’t know its been destroyed until the system clears itself out, which isn’t immediately. The physics engine may take until the next tick of the engine for this to happen.

Just try putting the flag in there… see if it works. It really easy to add.

If it doesn’t… well, I’m wrong.

1 Like