0
\$\begingroup\$

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")
                return;

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

        destroySelectedCubes = true;
    }
\$\endgroup\$
1

2 Answers 2

1
\$\begingroup\$

As Fábio Junqueira described, it looks like your problem is this:

BombA.Explode()
 - triggers BombB.Explode()
   - triggers BombA.Explode()
     - triggers BombB.Explode()

...and so on until all your memory is used up.

If bombs are one-shot, I'd solve this with something like the following:

public class Bomb : Monobehaviour
{
   private bool hasExploded = false;

   public void Explode()
   {
      // If we already blew up, don't do it again.
      if(hasExploded)
        return;

      // Time to blow up! Remember that we've blown up.
      hasExploded = true;

      // Do explosion logic here 
      // (find nearby items to damage/trigger, self-destruct, etc.)
   }
}
\$\endgroup\$
0
\$\begingroup\$

When this kind of error happens, its likely there is a infinite recursion loop in your code.

You need to make sure there that Physics2D.OverlapCircleAll is not returning the same collider more than once.

If that is not the problem, you can try to to replace the recursive function with a while loop

Edit:

First make sure that Physics2D.OverlapCircleAll is not returning the same collider more than once. I'm not at home right now to test your code, but by looking at it, it seems that an infinite recursion would happen right here:

TriggerBombAbility(cubeA);

//nerabyColliders returns cubeB
var nearbyColliders = Physics2D.OverlapCircleAll(specialCube.transform.position, explosionRadius);

TriggerBombAbility(cubeB);

//nerabyColliders returns cubeA
var nearbyColliders = Physics2D.OverlapCircleAll(specialCube.transform.position, explosionRadius);

TriggerBombAbility(cubeA);

//and this repeats forever....
\$\endgroup\$
4
  • \$\begingroup\$ An example would be really nice \$\endgroup\$ Dec 26, 2015 at 19:09
  • \$\begingroup\$ see my edit on the answer \$\endgroup\$ Dec 26, 2015 at 19:14
  • \$\begingroup\$ @Milen - looks like your bombs should have a hasAlreadyExploded flag. When calling TriggerBombAbility, first check if hasAlreadyExploded is true, and exit immediately if so. Otherwise, set it to true and continue with the behaviour. That way a bomb that triggers a neighbouring bomb to explode won't itself be triggered by the neighbour to explode again. \$\endgroup\$
    – DMGregory
    Dec 26, 2015 at 19:58
  • \$\begingroup\$ @DMGregory How can I add this flag? Sorry, I'm really new to Unity and game development in general. \$\endgroup\$ Dec 26, 2015 at 20:04

Not the answer you're looking for? Browse other questions tagged .