"Winning Event" randomly not being initiated

Hello,
My game is almost done, my levels are ready & as far as I can say, it’s not showing any errors anymore. But, one issue have been bugging me for a while and I was wondering if it’s just me. So, my levels are basically sometimes refusing to initiate the “Winning” event. The timer would run out & the attackers would be all killed, but the game doesn’t initiate the event it’s supposed to, even though I’m not getting any errors in the console. This doesn’t happen in a particular level & it seems to happen randomly, since sometimes I tried the same level with the exact same sequence of play & it works one time but not the other.

I didn’t include any code as I’ve gone through it countless times now & ended up commenting out my “unique code” & adding Rick’s instead, yet I got the same result. So, my code is now about the same as the one written in the lectures. So, if anyone encountered this issue & was able to solve it, please let me know, it would be much appreciated.

Hi Ahmad,

The best would be to add a few Debug.Logs to analyse the problem a bit further. Have you already tried that?

I did some debugging to track few elements that could be causing the issue, particularly the number of attackers at any given time & the the spawning delays (which are dynamic with the difficulty). The delay periods seems to be working as intended, and as shown in the attached picture in the inspector, the Attacker Count is reaching zero at the end, as it should. Yet, the level just remained stuck in this state. I couldn’t think of other elements that could into play, as the attacker count & level timer are the only 2 conditions for the winning event to be triggered.

Have you already watched lecture “Quick Bug Fix - Win Condition” (currently #171)? I’m wondering if your bug is the same as his.

Yes, I fixed that bug a while ago. I provided the level controller & level timer scripts below. Maybe there’s something obvious that I’m missing.


public class LevelController : MonoBehaviour
{
    [SerializeField] GameObject levelCompletionUI;
    [SerializeField] float completionDelay = 4f;
    [SerializeField] GameObject gameOverUI;
    [Header("Music")]
    [SerializeField] AudioClip levelCompletionSFX;
    [SerializeField] AudioClip gameOverSFX;
    [SerializeField] int attackerCount = 0; // for debugging
    bool levelTimerFinished = false;
    MusicPlayer musicPlayer;

    private void Start()
    {
        musicPlayer = FindObjectOfType<MusicPlayer>();
        levelCompletionUI.SetActive(false);
        musicPlayer.SetVolume(PlayerPrefsController.GetMasterVolume());
    }

    public void AnnounceAttackerSpawn()
    {
        attackerCount++;
    }

    public void AnnounceAttackerKill()
    {
        attackerCount--;
        if (attackerCount <= 0 && levelTimerFinished)
        {
            StartCoroutine(HandleWinCondition());
        }
    }

    IEnumerator HandleWinCondition()
    {
        levelCompletionUI.SetActive(true);
        musicPlayer.SetVolume(0);
        AudioSource.PlayClipAtPoint(levelCompletionSFX, Camera.main.transform.position);
        // Time.timeScale = 0;
        yield return new WaitForSeconds(completionDelay);
        FindObjectOfType<LevelLoader>().LoadNextScene();
    }

    public void HandleLossCondition()
    {
        gameOverUI.SetActive(true);
        musicPlayer.SetVolume(0);
        AudioSource.PlayClipAtPoint(gameOverSFX, Camera.main.transform.position);
        Time.timeScale = 0;
    }

    public void LevelTimerFinished()
    {
        levelTimerFinished = true;
        StopSpawners();
    }

    private void StopSpawners()
    {
        AttackerSpawner[] spawners = FindObjectsOfType<AttackerSpawner>();
        foreach (AttackerSpawner spawner in spawners)
        {
            spawner.StopSpawning();
        }
    }
}

public class LevelTimer : MonoBehaviour
{
    [Tooltip("Level Timer in Seconds")]
    [SerializeField] float levelTime = 10f;
    bool triggerLevelFinished = false;

    void Update()
    {
        if (triggerLevelFinished) { return; }
        GetComponent<Slider>().value = Time.timeSinceLevelLoad / levelTime * 100;
        bool timerFinished = Time.timeSinceLevelLoad >= levelTime;
        if (timerFinished)
        {
            FindObjectOfType<LevelController>().LevelTimerFinished();
            triggerLevelFinished = true;
        }
    }

Add Debug.Logs to your methods and log a few variables into your console to see if they have the expected values. There is a lot going on in your scripts, and we do not always know what is happening during runtime just by staring at code.

Privacy & Terms