Enemy count is always wrong

Weird title, kind of, but eh. Good morning, everyone. I have a pretty simple question similar to one that’s been answered plenty of times, but for some reason I am having all kinds of trouble getting this one tiny feature working in my game(s).

I have enemies. I want to add 1 to a static EnemyCount variable when an enemy is created, and subtract 1 from that same variable when one is destroyed. Sounds simple, is simple, yet it isn’t working for me. I have waves and such set up already and after a few waves (even the first wave sometimes) the count is all wrong.

What I’m doing is simple:

On the enemy:

function Start()
{
  GameManager.DebrisCount ++;
}

function OnDestroy()
{
  GameManager.DebrisCount --;
}

Shouldn’t this work? I’ve also tried OnDisable, tried putting it in a “Destroy” function I already have to handle other stuff, and yet it still doesn’t subtract correctly all the time.

To clarify, there’s nothing wrong with the adding, its count is fine if I don’t destroy anything and let it just keep creating enemies, but when I destroy them, well, I think you get it now.

I don’t have it doing anything to this variable anywhere else in any other script, and the OnDestroy function is only called once, so why is it always off, either too few remain by its count, or too many?

I’d appreciate any help you guys can give. Maybe my brain just isn’t on, or I really do have some other error in another script, although I’ve checked every other script in the game dozens of times looking for that stuff… Thanks. :slight_smile:

Hi.

Try to erease the Start-function

looks like this:

GameManager.DebrisCount ++;
 
function OnDestroy()
{
GameManager.DebrisCount --;
}

this is the only thing i could imagine. I hope this will help you =)

Incrementing and int in that fashion is not an atomic event. Reading a int (32bit) and writing is atomic, but DebrisCount++ is effectively equal to:

GameManager.DebrisCount = GameManager.DebrisCount + 1;

And that’s a read and a write. You should be doing a locked increment to avoid a race condition (since System.Threading.Increment(int i) doesn’t appear to be available in Unity).

//in GameManager
public static Object DebrisCountLock = new Object();

Lock(DebrisCountLock)
{
    GameManager.DebrisCount ++;
}
 
function OnDestroy()
{
    Lock(DebrisCountLock)
    {
        GameManager.DebrisCount --;
    }

}

Edit:
I’m not sure how Unity runs under the skin as I’m fairly new to it (what I’ve read seems that it’s single threaded so your approach may work ok, but some stuff appears to be async). In my normal work doing .net I’d always be super careful about many objects accessing one shared resource. Even if you think it’s always going to be a single threaded app, it’s easy enough to write and saves you down the line searching out those kinds of bugs when you multithread the code.