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, as always, 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;
// Physics2D.gravity *= -1;
// Physics.gravity *= -1;
}
Answer
First of all, you seem to have a bug in TriggerBombAbility()
: that return
should be a continue
.
Now a quick way to fix your issue of infinite recursion is to devise a way to mark a GameObject
as no longer triggerable. For instance you could have a hasBeenTriggered
boolean, defaulting to false, and you set it to true before triggering abilities:
case "Bomb":
specialCube.hasBeenTriggered = true;
TriggerBombAbility(specialCube);
break;
Then you only call TriggerSpecialCubeAbility()
if the ability hasn’t already been triggered:
var affectedCube = collider.gameObject;
if (!affectedCube.hasBeenTriggered)
{
TriggerSpecialCubeAbility(affectedCube);
Destroy(affectedCube);
}
Alternatively, you could put that check in Nevermind; this would require a check around TriggerSpecialCubeAbility()
itself and do an early exit:Destroy()
, too, and is therefore more complicated.
No comments:
Post a Comment