Had to do more refactoring since I also counted Waves and Time

The course is really showing its value since I’ve been able to refactor all of this and run it in my first attempt without errors :muscle: :video_game:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using UnityEngine;

public class ScoreKeeper : MonoBehaviour
{

    private static ScoreKeeper Instance;

    private UIDisplay uiDisplay;

    private int score = 0;
    private int time = 0;
    private int wave = 0;

    private void Awake() {
        uiDisplay = FindObjectOfType<UIDisplay>();
        ManageInstance();
    }

    private void ManageInstance() {
        if (Instance != null) {
            gameObject.SetActive(false);
            Destroy(gameObject);
        } else {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
    }

    public int GetScore() {
        return score;
    }

    public void ModifyScore(int amount) {
        score += amount;
        Mathf.Clamp(score, 0, int.MaxValue);
        uiDisplay.UpdateScore(score);
    }

    public void ResetScore() {
        score = 0;
    }

    public void ResetWaves() {
        wave = 0;
    }

    public int GetWave() {
        return wave;
    }

    public void ModifyWave(int amount) {
        wave += amount;
        Mathf.Clamp(wave, 0, int.MaxValue);
    }

    public int GetTimePlayed() {
        return time;
    }

    public void SetTimePlayed(float timePlayed) {
        time = (int)timePlayed;
    }
}
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class UIGameOver : MonoBehaviour
{
    [SerializeField] private TextMeshProUGUI scoreText;
    [SerializeField] private TextMeshProUGUI waveText;
    [SerializeField] private TextMeshProUGUI timeText;

    ScoreKeeper scoreKeeper;

    private void Awake() {
        scoreKeeper = FindObjectOfType<ScoreKeeper>();
    }

    private void Start() {
        scoreText.text = "score:\n" + scoreKeeper.GetScore().ToString("000000000");
        waveText.text = "wave: " + scoreKeeper.GetWave().ToString("0000");
        timeText.text = "time: " + scoreKeeper.GetTimePlayed().ToString("0000");
    }
}

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;

public class Health : MonoBehaviour
{
    [Header("General")]
    [SerializeField] private int healthMax = 50;
    [SerializeField] private ParticleSystem explosionFX;
    private int health;

    [Header("Camera Shake")]
    [SerializeField] private bool applyCameraShake = false;
    CameraShake cameraShake;

    [Header("Slow Motion")]
    [SerializeField] private bool applySlowMotion = false;
    [SerializeField] private float slowMotionDuration = 2f;
    [SerializeField] private float slowMotionTimeScale = 0.5f;
    private float sloMoTimer = 0f;
    private bool gotHit = false;

    [Header("Score Points per Death")]
    [SerializeField] bool isPlayer = false;
    [SerializeField] private int scorePerDeath = 10;

    private AudioPlayer audioPlayer;
    private ScoreKeeper scoreKeeper;
    private UIDisplay uiDisplay;
    LevelManager levelManager;

    private void Awake() {
        health = healthMax;
        levelManager = FindObjectOfType<LevelManager>();
        uiDisplay = FindObjectOfType<UIDisplay>();
        audioPlayer = FindObjectOfType<AudioPlayer>();
        cameraShake = Camera.main.GetComponent<CameraShake>();
        scoreKeeper = FindObjectOfType<ScoreKeeper>();
    }

    private void OnTriggerEnter2D(Collider2D collision) {
        DamageDealer damageDealer = collision.GetComponent<DamageDealer>();
        if(damageDealer != null) {
            TakeDamage(damageDealer.GetDamageValue());
            PlayExplosionFX();
            damageDealer.Hit();
            ShakeCamera();
            gotHit = true;
            audioPlayer.PlayDamageTakenClip();
            UpdateUI();
        }
    }

    private void UpdateUI() {
        if (isPlayer) {
            uiDisplay.UpdateHealth(healthMax, health);
        }
    }

    private void Update() {
        if (applySlowMotion && gotHit) {
            SlowMotion();
        }
    }

    private void TakeDamage(int damageValue) {
        health -= damageValue;
        if(health <= 0) {
            Die();
        }
    }

    private void Die() {
        if (!isPlayer) {
            scoreKeeper.ModifyScore(scorePerDeath);
        } else if (isPlayer) {
            scoreKeeper.SetTimePlayed(Time.timeSinceLevelLoad);
            levelManager.LoadDeathScene();
        }
        Destroy(gameObject);
    }

    private void PlayExplosionFX() {
        if (explosionFX != null) {
            ParticleSystem instance = Instantiate(explosionFX, transform.position, Quaternion.identity);
            Destroy(instance.gameObject, instance.main.duration + instance.main.startLifetime.constantMax);
        }
    }

    private void ShakeCamera() {
        if (cameraShake != null && applyCameraShake) {
            cameraShake.Play();
        }
    }

    private void SlowMotion() {
        Time.timeScale = slowMotionTimeScale + ((1 - slowMotionTimeScale) * (sloMoTimer / slowMotionDuration));
        sloMoTimer += Time.deltaTime;
        if (Time.timeScale >= 1) {
            Time.timeScale = 1;
            gotHit = false;
            sloMoTimer = 0f;
        }
    }

    public int GetHealth() {
        return health;
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemySpawner : MonoBehaviour
{
    [SerializeField] private List<WaveConfigurationSO> waveConfigurationSOs;
    [SerializeField] private float timeBetweenWaves = 0f;
    [SerializeField] private bool isLooping = true;
    private WaveConfigurationSO currentWave;
    private int waveCount = 0;
    private UIDisplay uiDisplay;
    private ScoreKeeper scoreKeeper;

    private void Awake() {
        uiDisplay = FindObjectOfType<UIDisplay>();
        scoreKeeper = FindObjectOfType<ScoreKeeper>();
    }

    private void Start() {
        StartCoroutine(SpawnEnemyWaves());
    }

    public WaveConfigurationSO GetCurrentWaveSO() {
        return currentWave;
    }
    private IEnumerator SpawnEnemyWaves() {
        do {
            foreach (WaveConfigurationSO waveConfigurationSO in waveConfigurationSOs) {
                currentWave = waveConfigurationSO;
                waveCount++;
                uiDisplay.UpdateWave(waveCount);
                scoreKeeper.ModifyWave(1);
                for (int i = 0; i < currentWave.GetEnemyCount(); i++) {
                    Instantiate(currentWave.GetEnemyPrefab(i),
                                currentWave.GetStartingWaypoint().position,
                                Quaternion.Euler(0, 0, 180),
                                transform);
                    yield return new WaitForSeconds(currentWave.GetRandomSpawnTime());
                }
                yield return new WaitForSeconds(timeBetweenWaves);
            }
        } while (isLooping);        
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor.SearchService;
using UnityEngine;
using UnityEngine.SceneManagement;

public class LevelManager : MonoBehaviour
{
    [SerializeField] private float deathLoadDelay = 2f;

    private ScoreKeeper scoreKeeper;

    private void Awake() {
        scoreKeeper = FindObjectOfType<ScoreKeeper>();
    }

    public void LoadGameScene() {
        if (SceneManager.GetActiveScene().buildIndex == 2) {
            ResetWavesAndScore();
        }
        SceneManager.LoadScene(1);
    }

    public void LoadMainMenu() {
        ResetWavesAndScore();
        SceneManager.LoadScene(0);
    }

    public void LoadDeathScene() {
        StartCoroutine(WaitAndLoad(2, deathLoadDelay));
    }

    public void QuitGame() {
        Application.Quit();
    }

    private IEnumerator WaitAndLoad(int sceneIndex, float delay) {
        yield return new WaitForSeconds(delay);
        SceneManager.LoadScene(sceneIndex);
    }

    private void ResetWavesAndScore() {
        scoreKeeper.ResetScore();
        scoreKeeper.ResetWaves();
    }
}

Good job with all that C#!

Privacy & Terms