[solved] Tracking object counts - question

Hi All,

I’m new to Unity and fiddling with an “Asteroids” type shooter just to get my feet wet. Anyway, I have an odd object count issue that I’d like some input on.

Currently, my “levels” are quite simple. Each “level” just consists of “levelNumber” of asteroids being instantiated. Once they’re all destroyed, the level number is incremented, and the new level number of asteroids is instantiated.

For tracking the asteroid count, I just increment a counter each time I instantiate a new asteroid. I have an “onTriggerEnter” function on the Asteroid that does the following:

  • Destroy the asteroid
  • Decrement the asteroid counter
  • Instantiate an explosion
  • Check to see if the asteroid count == 0
  • If so, call the asteroid instantiation function for the new level

The asteroid counter is only modified from the following 2 places in my code: 1) in the asteroid instantiation function for each newly created asteroid and 2) in the onTriggerEnter event of the asteroid each time an asteroid is destroyed.

Now, the problem. The above seems to work flawlessly until things get really busy (say 30-40 asteroids). At some point, my asteroid counter gets out of sync with the actual number of asteroids left in the game.

When this happens, it’s always off in the same direction. That is, the counter will reach zero at a time when one or two asteroids still exist in the game world.

Looking at my code, the only way I see that could be possible is if I decrement the counter without actually destroying an asteroid, but that doesn’t seem possible. That code just looks like this:

// Destroy the asteroid
Destroy(gameObject);
gm.asteroidCount--;

Obviously, I could adopt a different method of tracking the number of asteroids - such as just asking Unity for the number remaining. I’m sure though, that method would be more expensive and really doesn’t seem necessary. I just can’t figure out how the counter is getting off.

While it’s hard to tell, it seems to be somehow related to two or more asteroids being physically “overlapped” when they’re hit by a shot. I assume it’s possible for a single shot to trigger the collision event of multiple objects in a single frame in this case, right? Even if that happened though, the event should trigger in each separate instance of the event, and the counter should be properly decremented, right? At least, I think it should be… :wink:

Thoughts?

Thanks,

Jeff

Replying to my own question…

Thinking about this, it seems likely that my “onTriggerEnter” event is firing more than once for the same asteroid. Is this possible? If it were, then the first time would (properly) destroy the object and decrement the counter, but any further calls would decrement the counter and then find nothing to destroy. It seems that’s a likely way to arrive at my reported results.

Is this possible? If so, what’s the best way to avoid it? Maybe check if the current game object is null and just abort the onTriggerEnter event?

It seems odd that the event could fire for a non-existent object. Maybe it was already in the even queue before the object was destroyed?

Thanks,

Jeff

I ran into this problem when I was doing this. It is indeed possible for OnTriggerEnter() to be called more than once for various reasons…one thing I’ve done is something like

private var triggered = false;
function OnTriggerEnter() {
   if (triggered) return;
   triggered = true;
}

That way the function can’t run more than once. Another approach (which I ended up using in this case) is to bypass the entire issue, and tag your asteroids with a unique tag (something original like “asteroid”), then do

var asteroids = GameObject.FindGameObjectsWithTag("asteroid");
if (asteroids.length == 0) {
   // No more asteroids left, go to next level
}

This is more resource-intensive, but as long as you’re not doing it in Update but only when blowing up asteroids, it’s unlikely to make any noticeable difference and is 100% reliable no matter what.

–Eric

Very nice - though the buttons used for the controls seem odd to me and I can’t quite get the hang of them… :wink:

Thanks for that - that’s certainly what it seemed like.

Yep, I like this. I’ve implemented something similar and it seems to have solved the problem.

Yeah, that’s exactly what I was thinking when I made this comment:

Anyway, problem solved. Thanks Eric.

Jeff