Summoning Uncounted GameObjects

Looking for an error in my code. Im trying to random summon 3 types of enemys, and it keeps summoning unrecorded guys. by the time i killed them all at level 5 it failed to summon the boss because my enemys remaining counter was at -12 i was watching and it kept summoning an extra guy every now and then. when my enemys die they should and look like they are subrtacting 1 from eremaining, and adding 1 to summon. cant figgure out where the extra unrecorded summons are coming from.

Declaration of varriables

public Transform espell;
public Transform emelee;
public Transform eranged;
public Transform ERBoss;
static public int CURLEVEL = 1;
static public int EREMAINING = 0;
static public int summon;
static float EnemySpell = 0;
static float EnemyMelee = 0;
static float EnemyRanged = 0;
static public int Boss = 5;
static public bool BossAlive = false;
static public float KillCount = 0;
static public float TempKillCount = 0;

Code for summoning

    if (CURLEVEL < Boss)
    {
        if (TempKillCount >= CURLEVEL * 2)
        {
            TempKillCount = TempKillCount - (CURLEVEL * 2);
            CURLEVEL += 1;
            summon += 1;
        }

        // Summon New Enemys
        while (summon > 0)
        {
            float lu = Random.Range(1, 100);
            if (lu < 13)
            { ESPEED += .25f; }
            else if ((lu > 12) && (lu < 26))
            { EROTATION += .05f; }
            else if ((lu > 25) && (lu < 51))
            { EnemySpell += 1; }
            else if ((lu > 50) && (lu < 76))
            { EnemyRanged += 1; }
            else if (lu > 75)
            { EnemyMelee += 1; }
            if (EnemySpell <= 0 & EnemyMelee <= 0 & EnemyRanged <= 0)
            { EnemySpell += 1; }
            summon -= 1;
        }
        if (EnemySpell > 0)
        {
            Vector3 position = new Vector3(Random.Range(-18, 18), 1, Random.Range(-18, 18));
            Instantiate(espell, position, Quaternion.identity);
            EnemySpell -= 1;
            EREMAINING += 1;
        }
        if (EnemyMelee > 0)
        {
            Vector3 position2 = new Vector3(Random.Range(-18, 18), 1, Random.Range(-18, 18));
            Instantiate(emelee, position2, Quaternion.identity);
            EnemyMelee -= 1;
            EREMAINING += 1;
        }
        if (EnemyRanged > 0)
        {
            Vector3 position3 = new Vector3(Random.Range(-18, 18), 1, Random.Range(-18, 18));
            Instantiate(eranged, position3, Quaternion.identity);
            EnemyRanged -= 1;
            EREMAINING += 1;
        }
    }
    if (CURLEVEL >= Boss && EREMAINING == 0 && BossAlive == false)
    {
        Debug.Log(Boss + " Boss has almost been summoned");
        Vector3 ERB = new Vector3(11, 4, -9);
        Instantiate(ERBoss, ERB, Quaternion.identity);
        BossAlive = true;
        Debug.Log(Boss + " Boss has been summoned");
    }
    if (CURLEVEL >= Boss && EREMAINING != 0 && BossAlive == false)
    {
        Debug.Log(" Boss Summon Fail... EREMAINING = " + EREMAINING);
    }

Death code for my enemys:

    //Out of life
    if (curhp < 1 || dead == true)
    {
        Level.EREMAINING -= 1;
        Level.summon += 1;
        Level.KillCount += 1;
        Level.TempKillCount += 1;
        MainCharacter.SCORE += 124;
        MainCharacter.CURXP += 20;
        Instantiate(explosion, gameObject.transform.position, Quaternion.identity);
        Destroy(gameObject);
    }

Well, maybe your “Death code” is executed several times for the same enemy? Where and when is it executed? Have you tried placing some Debug.Logs?

In any way the condition for your boss shouldn’t be (EREMAINING == 0), just use (EREMAINING <= 0). However it might be a good idea to find out what’s causing your problems since if your death code runs twice you would mess up your score and xp.

I guess “EREMAINING” is a static int? What you can do as well is replacing your static field with a static property using a private backing field:

Instead of

public static int EREMAINING;

you would do:

private static int _EREMAINING;
public static int EREMAINING
{
    get { return _EREMAINING;}
    set
    {
        Debug.Log("EREMAINING was " + _EREMAINING + " and is going to be set to " + value);
        _EREMAINING = value;
    }
}

This temporary replacement will give you a debug log whenever the value of “EREMAINING” is changed. It will tell you the old value as well as the new one. In addition you get a stacktrace of the debug log call so you can easily figure out from where this change was made.