Created
August 10, 2023 14:00
-
-
Save rafaelbriet/b9745bddbc5d3f31167e18710f8a7678 to your computer and use it in GitHub Desktop.
This is the GameManager class of my game "The Adventures of The Lone Bounty Hunter". I used it as an example of a class with multiple responsibilities and practices to be avoided. I detailed these issues in an article published on my blog, where I discuss the importance of writing clean and organized code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using TMPro; | |
using UnityEngine; | |
using UnityEngine.Playables; | |
using UnityEngine.SceneManagement; | |
using UnityEngine.Timeline; | |
using UnityEngine.UI; | |
public class GameManager : MonoBehaviour | |
{ | |
public static bool IsGamePaused { get; private set; } | |
public GameCamera GameCamera { get; private set; } | |
public GameData CurrentGameData { get; private set; } = new GameData(); | |
public GameData GameStats { get; private set; } = new GameData(); | |
public PlayerCharacter PlayerCharacter { get => playerCharacter; } | |
public int CurrentLevel { get => currentLevel; } | |
public GameObject LevelBoss { get => levelBoss; } | |
public LevelData CurrentLevelData { get => levelData[CurrentLevel]; } | |
public int NumberOfLevels { get => levelData.Count - 1; } | |
public float LootChanceModifier { get => lootChanceModifier; set => lootChanceModifier = value; } | |
public bool HealWhenEnemyIsKilled { get => healWhenEnemyIsKilled; set => healWhenEnemyIsKilled = value; } | |
public int HealWhenEnemyIsKilledAmount { get => healWhenEnemyIsKilledAmount; set => healWhenEnemyIsKilledAmount = value; } | |
public float HealWhenEnemyIsKilledChance { get => healWhenEnemyIsKilledChance; set => healWhenEnemyIsKilledChance = value; } | |
[Header("Weapons Data")] | |
public List<WeaponData> WeaponsData; | |
[Header("Weapons Data"), SerializeField] | |
private List<LevelData> levelData; | |
[Header("Managers"), SerializeField] | |
private List<GameObject> managersPrefabs; | |
[Header("Player"), SerializeField] | |
private GameObject playerPrefab; | |
[Header("Prefabs"), SerializeField] | |
private GameObject whiskeyPrefab; | |
[Header("Debug"), SerializeField] | |
public bool CanSpawnEnemies = true; | |
[SerializeField] | |
private GameObject debugCanvas; | |
[SerializeField] | |
private TMP_InputField debugLevelIndex; | |
[SerializeField] | |
private bool startGameFromFirstLevel = true; | |
[SerializeField] | |
private int firstLevelIndex = default; | |
[SerializeField] | |
private TMP_InputField weaponNameToGive; | |
[SerializeField] | |
private TMP_InputField powerUpNameToGive; | |
[SerializeField] | |
private Toggle hideCursorToggle; | |
[SerializeField] | |
private CanvasGroup pauseMenuCanvasGroup; | |
[SerializeField] | |
private Canvas playerStatsCanvas; | |
[SerializeField] | |
private TextMeshProUGUI shotsFiredTextMesh; | |
[SerializeField] | |
private TextMeshProUGUI shotsHitTextMesh; | |
[SerializeField] | |
private TextMeshProUGUI accuracyTextMesh; | |
private List<GameObject> levelEnemies; | |
private GameObject levelBoss; | |
private MapGenerator mapGenerator; | |
private GraphCreator graphCreator; | |
private PlayerCharacter playerCharacter; | |
private int currentLevel = 0; | |
private UIManager uiManager; | |
private DateTime gameSectionStart; | |
private int totalShotsFired; | |
private int totalShotsHit; | |
private float lootChanceModifier; | |
private bool healWhenEnemyIsKilled; | |
private int healWhenEnemyIsKilledAmount; | |
private float healWhenEnemyIsKilledChance; | |
private PowerUpManager powerUpManager; | |
private GameDataManager gameDataManager; | |
private bool isNewGame; | |
private GameOptionsLoader gameOptionsLoader; | |
private SoundEffectsManager soundEffectsManager; | |
private GameCamera gameCamera; | |
private PlayableDirector bossIntroPlayableDirector; | |
private Coroutine bossIntroCoroutine; | |
public event Action PlayerSpawned; | |
public event Action GamePaused; | |
public event Action GameUnpaused; | |
public event Action GameFinished; | |
public event Action OnLevelStart; | |
public event Action OnLevelCompleted; | |
#region Unity API Calls | |
private void Awake() | |
{ | |
mapGenerator = FindObjectOfType<MapGenerator>(); | |
graphCreator = FindObjectOfType<GraphCreator>(); | |
uiManager = FindObjectOfType<UIManager>(); | |
GameCamera = FindObjectOfType<GameCamera>(); | |
powerUpManager = GetComponent<PowerUpManager>(); | |
gameDataManager = GetComponent<GameDataManager>(); | |
gameSectionStart = DateTime.Now; | |
isNewGame = GameObject.Find(GameDataStrings.LoadGameObjectName) == null; | |
if (isNewGame == false) | |
{ | |
CurrentGameData = gameDataManager.Load(); | |
currentLevel = CurrentGameData.CurrentLevelIndex; | |
totalShotsFired = CurrentGameData.PlayerShotsFired; | |
totalShotsHit = CurrentGameData.PlayerShotsHit; | |
} | |
foreach (GameObject manager in managersPrefabs) | |
{ | |
Instantiate(manager); | |
} | |
} | |
private void Start() | |
{ | |
gameOptionsLoader = FindObjectOfType<GameOptionsLoader>(); | |
soundEffectsManager = FindObjectOfType<SoundEffectsManager>(); | |
gameCamera = FindObjectOfType<GameCamera>(); | |
bossIntroPlayableDirector = gameCamera.GetComponent<PlayableDirector>(); | |
TimelineAsset timeline = bossIntroPlayableDirector.playableAsset as TimelineAsset; | |
TrackAsset trackAsset = timeline.GetOutputTrack(2); | |
bossIntroPlayableDirector.SetGenericBinding(trackAsset, soundEffectsManager.BossStartAudioSource); | |
#if UNITY_EDITOR | |
if (startGameFromFirstLevel == false) | |
{ | |
if (firstLevelIndex > 0 && firstLevelIndex < levelData.Count) | |
{ | |
currentLevel = firstLevelIndex; | |
} | |
else | |
{ | |
Debug.LogError("Level index must be between 0 and " + (levelData.Count - 1)); | |
} | |
} | |
#endif | |
StartNewLevel(); | |
isNewGame = true; | |
debugCanvas.SetActive(false); | |
playerStatsCanvas.gameObject.SetActive(false); | |
UpdatePlayerStatsDebugUI(); | |
} | |
private void Update() | |
{ | |
if (Input.GetKeyDown(KeyCode.Escape)) | |
{ | |
if (IsGamePaused == false) | |
{ | |
PauseGame(); | |
} | |
else if (IsGamePaused == true) | |
{ | |
UnpauseGame(); | |
} | |
} | |
CheatsInput(); | |
} | |
private void OnDisable() | |
{ | |
UnpauseGame(); | |
HideCursor(false); | |
} | |
#endregion | |
[System.Diagnostics.Conditional("ENABLE_CHEATS")] | |
private void CheatsInput() | |
{ | |
if (Input.GetKeyDown(KeyCode.Comma)) | |
{ | |
if (IsGamePaused == false) | |
{ | |
PauseGame(); | |
} | |
else | |
{ | |
UnpauseGame(); | |
} | |
DisplayDebugCanvas(); | |
} | |
if (Input.GetKeyDown(KeyCode.Space)) | |
{ | |
StartNewLevel(); | |
} | |
} | |
private void SaveGameData() | |
{ | |
// Game Data | |
CurrentGameData.GameVersion = Application.version; | |
CurrentGameData.PlayTimeTicks = CalculatePlayTime(CurrentGameData.PlayTimeTicks); | |
gameSectionStart = DateTime.Now; | |
// Level Data | |
CurrentGameData.CurrentLevelIndex = currentLevel; | |
CurrentGameData.SpawnPointForEnemiesAlive = new List<Vector3>(); | |
if (levelEnemies != null) | |
{ | |
foreach (GameObject enemy in levelEnemies) | |
{ | |
if (enemy == null) | |
{ | |
continue; | |
} | |
CurrentGameData.SpawnPointForEnemiesAlive.Add(enemy.GetComponent<AICharacter>().SpawnPosition); | |
} | |
} | |
CurrentGameData.CratesNotBroken = new List<Vector3>(); | |
GameObject[] crates = GameObject.FindGameObjectsWithTag("Crate"); | |
foreach (GameObject crate in crates) | |
{ | |
CurrentGameData.CratesNotBroken.Add(crate.transform.position); | |
} | |
CurrentGameData.PickUpsNotCollected = new List<Vector3>(); | |
GameObject[] pickups = GameObject.FindGameObjectsWithTag("PickUp"); | |
foreach (GameObject item in pickups) | |
{ | |
CurrentGameData.PickUpsNotCollected.Add(item.transform.position); | |
} | |
// Player Data | |
CurrentGameData.CurrentPlayerHitPoints = playerCharacter.CurrentHitPoints; | |
CurrentGameData.CurrentPlayerBounty = playerCharacter.Bounty; | |
CurrentGameData.CurrentWeaponIndex = playerCharacter.CurrentWeaponIndex; | |
CurrentGameData.PlayerWeapons = new List<PlayerWeaponSaveData>(); | |
foreach (WeaponItem weaponItem in playerCharacter.WeaponInventory) | |
{ | |
if (weaponItem != null) | |
{ | |
PlayerWeaponSaveData playerWeaponSaveData = new PlayerWeaponSaveData(weaponItem.WeaponData.Name, weaponItem.CurrentAmmo); | |
CurrentGameData.PlayerWeapons.Add(playerWeaponSaveData); | |
} | |
} | |
CurrentGameData.PlayerPowerUps = new List<string>(); | |
foreach (PowerUp powerUp in powerUpManager.PowerUpsBought) | |
{ | |
CurrentGameData.PlayerPowerUps.Add(powerUp.Name); | |
} | |
CurrentGameData.CanRevive = playerCharacter.CanRevive; | |
// Player Stats | |
CurrentGameData.PlayerShotsFired = totalShotsFired; | |
CurrentGameData.PlayerShotsHit = totalShotsHit; | |
CurrentGameData.PlayerAccuracy = CalculateAcuracy(); | |
gameDataManager.Save(CurrentGameData); | |
} | |
public void SaveBeforeBossFight() | |
{ | |
CurrentGameData.HasReachedBossFigth = true; | |
SaveGameData(); | |
} | |
public void SaveOnLevelStart() | |
{ | |
CurrentGameData.RoomsName = new List<string>(); | |
foreach (GameObject room in mapGenerator.Rooms) | |
{ | |
CurrentGameData.RoomsName.Add(room.name.Replace("(Clone)", "")); | |
} | |
SaveGameData(); | |
} | |
public void SaveOnLevelCompleted() | |
{ | |
CurrentGameData.HasDefeatedBoss = true; | |
SaveGameData(); | |
CurrentGameData.HasReachedBossFigth = false; | |
CurrentGameData.HasDefeatedBoss = false; | |
} | |
public void SaveOnPlayerDeath() | |
{ | |
GameData gameData = gameDataManager.Load(); | |
gameData.PlayTimeTicks = CalculatePlayTime(gameData.PlayTimeTicks); | |
gameData.PlayerDeaths++; | |
gameDataManager.Save(gameData); | |
} | |
private long CalculatePlayTime(long savedPlayTimeTicks) | |
{ | |
DateTime gameSectionEnd = DateTime.Now; | |
TimeSpan savedPlayTime = new TimeSpan(savedPlayTimeTicks); | |
TimeSpan currentPlayTime = gameSectionEnd - gameSectionStart; | |
TimeSpan totalPlayTime = savedPlayTime.Add(currentPlayTime); | |
return totalPlayTime.Ticks; | |
} | |
private int CalculateAcuracy() | |
{ | |
if (totalShotsFired <= 0) | |
{ | |
return 0; | |
} | |
return totalShotsHit * 100 / totalShotsFired; | |
} | |
public WeaponData GetWeapon(string name) | |
{ | |
WeaponData weapon = WeaponsData.Find(w => w.Name == name); ; | |
return weapon; | |
} | |
public void PauseGame() | |
{ | |
IsGamePaused = true; | |
Time.timeScale = 0; | |
GamePaused?.Invoke(); | |
} | |
public void UnpauseGame() | |
{ | |
IsGamePaused = false; | |
Time.timeScale = 1; | |
GameUnpaused?.Invoke(); | |
} | |
public void StartNewLevel() | |
{ | |
uiManager.HideScreenFader(); | |
uiManager.HideBossHealthBar(); | |
GameObject[] pickups = GameObject.FindGameObjectsWithTag("PickUp"); | |
foreach (GameObject item in pickups) | |
{ | |
DestroyImmediate(item); | |
} | |
GameObject[] bullets = GameObject.FindGameObjectsWithTag("Bullet"); | |
foreach (GameObject item in bullets) | |
{ | |
Destroy(item); | |
} | |
GameObject[] charactersDeath = GameObject.FindGameObjectsWithTag("CharacterDeath"); | |
foreach (GameObject character in charactersDeath) | |
{ | |
Destroy(character); | |
} | |
if (isNewGame) | |
{ | |
mapGenerator.CreateNewMap(levelData[currentLevel].NumberOfRooms); | |
GameObject[] crates = GameObject.FindGameObjectsWithTag("Crate"); | |
foreach (GameObject crate in crates) | |
{ | |
Crate c = crate.GetComponent<Crate>(); | |
c.CrateDestroyed += CrateDestroyed; | |
} | |
} | |
else | |
{ | |
mapGenerator.CreateMap(CurrentGameData.RoomsName); | |
GameObject[] crates = GameObject.FindGameObjectsWithTag("Crate"); | |
foreach (GameObject crate in crates) | |
{ | |
bool isPositionSaved = CurrentGameData.CratesNotBroken.Any(position => position == crate.transform.position); | |
if (isPositionSaved) | |
{ | |
Crate c = crate.GetComponent<Crate>(); | |
c.CrateDestroyed += CrateDestroyed; | |
} | |
else | |
{ | |
DestroyImmediate(crate); | |
} | |
} | |
foreach (Vector3 pickUpPositionSaved in CurrentGameData.PickUpsNotCollected) | |
{ | |
Instantiate(whiskeyPrefab, pickUpPositionSaved, Quaternion.identity); | |
} | |
} | |
graphCreator.CreateGraph(); | |
StartCoroutine(BossRoomTrigger()); | |
if (playerCharacter == null) | |
{ | |
SpawnPlayer(); | |
} | |
else | |
{ | |
ResetPlayer(); | |
} | |
if (CurrentGameData.HasDefeatedBoss == false && CanSpawnEnemies) | |
{ | |
SpawnEnemies(); | |
} | |
OnLevelStart?.Invoke(); | |
if (isNewGame) | |
{ | |
SaveOnLevelStart(); | |
} | |
} | |
private IEnumerator BossRoomTrigger() | |
{ | |
yield return null; | |
BossRoomBlockerTrigger bossRoomBlockerTrigger = GameObject.FindGameObjectWithTag("BossRoomBlocker").GetComponent<BossRoomBlockerTrigger>(); | |
bossRoomBlockerTrigger.BossRoomBlockerCreated += BossRoomBlockerCreated; | |
bossRoomBlockerTrigger.BossRoomBlockerCreated += BossIntroSetup; | |
} | |
private void BossIntroSetup() | |
{ | |
soundEffectsManager.StopAllCoroutines(); | |
gameCamera.Target = null; | |
playerCharacter.CanMove = false; | |
soundEffectsManager.BossRoomEntered(); | |
Transform bossSpawnPoint = GameObject.FindGameObjectWithTag("BossSpawnPoint").transform; | |
TimelineAsset timeline = bossIntroPlayableDirector.playableAsset as TimelineAsset; | |
TrackAsset trackAsset = timeline.GetOutputTrack(1); | |
TimelineClip timelineClip = trackAsset.GetClips().First(); | |
GameObjectClip gameObjectClip = timelineClip.asset as GameObjectClip; | |
gameObjectClip.TransformReference.exposedName = new PropertyName("TransformReference"); | |
bossIntroPlayableDirector.SetReferenceValue(gameObjectClip.TransformReference.exposedName, bossSpawnPoint); | |
if (bossIntroCoroutine != null) | |
{ | |
StopCoroutine(bossIntroCoroutine); | |
} | |
GameObject bossRoomBlocker = GameObject.FindGameObjectWithTag("BossRoomBlocker").GetComponent<BossRoomBlockerTrigger>().Blocker; | |
bossIntroCoroutine = StartCoroutine(PlayBossIntroTimelime(bossRoomBlocker.GetComponent<BossRoomBlocker>().ShakeDuration)); | |
} | |
private IEnumerator PlayBossIntroTimelime(float waitForSeconds) | |
{ | |
yield return new WaitForSeconds(waitForSeconds); | |
bossIntroPlayableDirector.Play(); | |
} | |
public void BossIntroStart() | |
{ | |
} | |
public void BossIntroEnd() | |
{ | |
gameCamera.Target = playerCharacter.transform; | |
playerCharacter.CanMove = true; | |
soundEffectsManager.PlayBossFightMusic(); | |
} | |
private void CrateDestroyed() | |
{ | |
totalShotsHit++; | |
graphCreator.CreateGraph(); | |
UpdatePlayerStatsDebugUI(); | |
} | |
private void BossRoomBlockerCreated() | |
{ | |
graphCreator.CreateGraph(); | |
} | |
private void SpawnEnemies() | |
{ | |
if (levelBoss != null) | |
{ | |
Destroy(levelBoss); | |
} | |
if (levelEnemies != null) | |
{ | |
foreach (GameObject enemy in levelEnemies) | |
{ | |
Destroy(enemy); | |
} | |
} | |
levelBoss = null; | |
levelEnemies = new List<GameObject>(); | |
List<Transform> enemiesSpawnPoints = mapGenerator.EnemiesSpawnPoint; | |
Transform bossSpawnPoint = mapGenerator.BossSpawnPoint; | |
if (isNewGame) | |
{ | |
foreach (Transform spawnPoint in enemiesSpawnPoints) | |
{ | |
SpawnLevelEnemy(spawnPoint); | |
} | |
} | |
else | |
{ | |
foreach (Transform spawnPoint in enemiesSpawnPoints) | |
{ | |
foreach (Vector3 spawnPosinSaved in CurrentGameData.SpawnPointForEnemiesAlive) | |
{ | |
if (spawnPoint.position == spawnPosinSaved) | |
{ | |
SpawnLevelEnemy(spawnPoint); | |
} | |
} | |
} | |
} | |
GameObject bossToSpawn = levelData[currentLevel].BossPrefab[UnityEngine.Random.Range(0, levelData[currentLevel].BossPrefab.Length)]; | |
levelBoss = Instantiate(bossToSpawn, bossSpawnPoint.transform.position, Quaternion.identity, bossSpawnPoint.transform); | |
AICharacter bossCharacter = levelBoss.GetComponent<AICharacter>(); | |
bossCharacter.CharacterDied += OnCharacterDeath; | |
bossCharacter.CharacterTookDamage += OnEnemyTookDamage; | |
bossCharacter.LootChanceModifier = LootChanceModifier; | |
} | |
private void SpawnLevelEnemy(Transform spawnPoint) | |
{ | |
GameObject enemyToSpawn = levelData[currentLevel].EnemyPrefab[UnityEngine.Random.Range(0, levelData[currentLevel].EnemyPrefab.Length)]; | |
GameObject enemy = Instantiate(enemyToSpawn, spawnPoint.position, Quaternion.identity, spawnPoint); | |
AICharacter enemyCharacter = enemy.GetComponent<AICharacter>(); | |
enemyCharacter.CharacterDied += OnCharacterDeath; | |
enemyCharacter.CharacterTookDamage += OnEnemyTookDamage; | |
enemyCharacter.LootChanceModifier = LootChanceModifier; | |
enemyCharacter.SpawnPosition = spawnPoint.position; | |
levelEnemies.Add(enemy); | |
} | |
private void OnEnemyTookDamage(Character character) | |
{ | |
totalShotsHit++; | |
UpdatePlayerStatsDebugUI(); | |
} | |
public void SetAimAssist(bool isAimAssistOn, float aimAssistRadius) | |
{ | |
playerCharacter.IsAimAssistOn = isAimAssistOn; | |
playerCharacter.AimAssistRadius = aimAssistRadius; | |
} | |
private void SpawnPlayer() | |
{ | |
Vector3 playerSpawnPosition = mapGenerator.PlayerSpawnPosition; | |
if (CurrentGameData.HasReachedBossFigth) | |
{ | |
foreach (GameObject room in mapGenerator.Rooms) | |
{ | |
if (room.name.Contains("RoomBoss")) | |
{ | |
playerSpawnPosition = room.transform.Find("RoomEnterNode").position; | |
break; | |
} | |
} | |
} | |
playerCharacter = Instantiate(playerPrefab, playerSpawnPosition, Quaternion.identity).GetComponent<PlayerCharacter>(); | |
playerCharacter.CharacterDied += OnCharacterDeath; | |
playerCharacter.PlayerFiredCount += OnPlayerFired; | |
if (isNewGame) | |
{ | |
playerCharacter.AddWeaponToInventory(GetWeapon("Revolver")); | |
playerCharacter.ChangeWeapon(0, true); | |
} | |
else | |
{ | |
playerCharacter.CurrentHitPoints = CurrentGameData.CurrentPlayerHitPoints; | |
playerCharacter.Bounty = CurrentGameData.CurrentPlayerBounty; | |
foreach (string powerUpName in CurrentGameData.PlayerPowerUps) | |
{ | |
powerUpManager.GivePowerUp(powerUpName, this); | |
} | |
for (int i = 0; i < CurrentGameData.PlayerWeapons.Count; i++) | |
{ | |
PlayerWeaponSaveData weaponSaveData = CurrentGameData.PlayerWeapons[i]; | |
WeaponData weaponData = GetWeapon(weaponSaveData.Name); | |
WeaponItem weaponItem = new WeaponItem(weaponData, weaponSaveData.CurrentAmmo); | |
playerCharacter.WeaponInventory[i] = weaponItem; | |
} | |
playerCharacter.CanRevive = CurrentGameData.CanRevive; | |
playerCharacter.LoadWeaponFromFile(CurrentGameData.CurrentWeaponIndex); | |
if (CurrentGameData.HasDefeatedBoss) | |
{ | |
LevelCompleted(); | |
} | |
} | |
SetAimAssist(gameOptionsLoader.GameOptions.AimAssist, gameOptionsLoader.GameOptions.AimAssistStrength); | |
PlayerSpawned?.Invoke(); | |
GameCamera.Target = playerCharacter.transform; | |
} | |
private void ResetPlayer() | |
{ | |
playerCharacter.gameObject.SetActive(true); | |
playerCharacter.transform.position = mapGenerator.PlayerSpawnPosition; | |
playerCharacter.ResetWeaponsAmmo(); | |
ProtectPlayer(false); | |
} | |
private void OnPlayerFired() | |
{ | |
totalShotsFired += playerCharacter.Weapon.WeaponData.BulletAmount + 1; | |
UpdatePlayerStatsDebugUI(); | |
} | |
private void WhenEnemyIsKilledHeal() | |
{ | |
if (HealWhenEnemyIsKilled == false) | |
{ | |
return; | |
} | |
if (UnityEngine.Random.Range(0f, 1f) < healWhenEnemyIsKilledChance) | |
{ | |
playerCharacter.Heal(healWhenEnemyIsKilledAmount); | |
} | |
} | |
private void ProtectPlayer(bool hasProtection) | |
{ | |
playerCharacter.IsDebugInvincible = hasProtection; | |
} | |
private void OnCharacterDeath(Character character) | |
{ | |
if (character.CompareTag("Enemy")) | |
{ | |
CurrentGameData.PlayerKills++; | |
playerCharacter.PlayerBounty += character.Bounty; | |
levelEnemies.Remove(character.gameObject); | |
WhenEnemyIsKilledHeal(); | |
} | |
else if (character.CompareTag("Boss")) | |
{ | |
CurrentGameData.PlayerKills++; | |
playerCharacter.PlayerBounty += character.Bounty; | |
StartCoroutine(GameCamera.ZoomOut(12)); | |
soundEffectsManager.PlayerDefeatedBoss(); | |
uiManager.ShowScreenFader(7f, LevelCompleted); | |
WhenEnemyIsKilledHeal(); | |
ProtectPlayer(true); | |
} | |
else if (character.CompareTag("Player")) | |
{ | |
StartCoroutine(GameCamera.ZoomIn(1, character.transform.position)); | |
SaveOnPlayerDeath(); | |
uiManager.ShowScreenFader(2f, GameOver); | |
} | |
GameObject deathCharacter = Instantiate(character.DeathPrefab, character.transform.position, Quaternion.identity, character.transform.parent); | |
SpriteRenderer deathCharacterSpriteRenderer = deathCharacter.GetComponentInChildren<SpriteRenderer>(); | |
deathCharacterSpriteRenderer.flipX = character.GetComponentInChildren<SpriteRenderer>().flipX; | |
character.CharacterDied -= OnCharacterDeath; | |
character.gameObject.SetActive(false); | |
} | |
private void GameOver() | |
{ | |
// TODO: Implement game over stuff | |
SceneManager.LoadScene("GameOver"); | |
} | |
private void LevelCompleted() | |
{ | |
if (currentLevel >= levelData.Count - 1) | |
{ | |
GameCompleted(); | |
} | |
else | |
{ | |
SceneManager.LoadScene("LevelCompleted", LoadSceneMode.Additive); | |
} | |
if (isNewGame) | |
{ | |
currentLevel += 1; | |
GameCamera.ResetCamera(); | |
SaveOnLevelCompleted(); | |
} | |
playerCharacter.gameObject.SetActive(false); | |
OnLevelCompleted?.Invoke(); | |
} | |
private void GameCompleted() | |
{ | |
SceneManager.LoadScene("GameCompleted", LoadSceneMode.Additive); | |
GameFinished?.Invoke(); | |
if (isNewGame) | |
{ | |
GameCamera.ResetCamera(); | |
} | |
} | |
#region Debugging Helpers | |
private void UpdatePlayerStatsDebugUI() | |
{ | |
shotsFiredTextMesh.text = $"Shots Fired: {totalShotsFired}"; | |
shotsHitTextMesh.text = $"Shots Hit: {totalShotsHit}"; | |
accuracyTextMesh.text = $"Accuracy: {CalculateAcuracy()}"; | |
} | |
private void DisplayDebugCanvas() | |
{ | |
if (debugCanvas.activeInHierarchy == false) | |
{ | |
Cursor.visible = true; | |
} | |
else | |
{ | |
HideCursor(hideCursorToggle.isOn); | |
} | |
debugCanvas.SetActive(!debugCanvas.activeInHierarchy); | |
} | |
public void GivePlayerWeapon() | |
{ | |
playerCharacter.AddWeaponToInventory(GetWeapon(weaponNameToGive.text)); | |
} | |
public void GivePlayerPowerUp() | |
{ | |
powerUpManager.GivePowerUp(powerUpNameToGive.text); | |
} | |
public void DebugDisplayAIState() | |
{ | |
foreach (GameObject character in levelEnemies) | |
{ | |
StateMachine enemy = character.GetComponent<StateMachine>(); | |
enemy.DisplayStateMachineDebugger = !enemy.DisplayStateMachineDebugger; | |
} | |
StateMachine boss = levelBoss.GetComponent<StateMachine>(); | |
boss.DisplayStateMachineDebugger = !boss.DisplayStateMachineDebugger; | |
} | |
public void GoToLevel() | |
{ | |
if (int.TryParse(debugLevelIndex.text, out int index)) | |
{ | |
if (index >= 0 && index < levelData.Count ) | |
{ | |
currentLevel = index; | |
StartNewLevel(); | |
} | |
else | |
{ | |
Debug.LogWarning("Level index must be between 0 and " + (levelData.Count - 1)); | |
} | |
} | |
else | |
{ | |
Debug.LogWarning("Level index must be an int."); | |
} | |
} | |
public void PlayerInvulnerability(bool isInvulnerable) | |
{ | |
playerCharacter.IsInvulnerable = isInvulnerable; | |
} | |
public void PlayerHasInfiniteAmmo(bool isAmmoInfinite) | |
{ | |
playerCharacter.Weapon.IsAmmoInfinite = isAmmoInfinite; | |
} | |
public void MovePlayerToBossRoom() | |
{ | |
GameObject gameMap = GameObject.FindGameObjectWithTag("GameMap"); | |
GameObject boosRoom = null; | |
for (int i = gameMap.transform.childCount - 1; i >= 0; i--) | |
{ | |
if (gameMap.transform.GetChild(i).name.Contains("RoomBoss")) | |
{ | |
boosRoom = gameMap.transform.GetChild(i).gameObject; | |
break; | |
} | |
} | |
if (boosRoom == null) | |
{ | |
Debug.LogError("No boss Room was found in this map"); | |
return; | |
} | |
foreach (Transform child in boosRoom.transform) | |
{ | |
if (child.name.Contains("RoomEnterNode")) | |
{ | |
playerCharacter.transform.position = child.transform.position; | |
break; | |
} | |
} | |
} | |
public void EnableFreeCamera(bool isFreeCamera) | |
{ | |
gameCamera.IsFollowingTarget = isFreeCamera; | |
} | |
public void HideHUD(bool isHUDHidden) | |
{ | |
uiManager.SetHUDAlpha(Convert.ToInt32(!isHUDHidden)); | |
} | |
public void DisableEnemiesSpawn(bool canSpawnEnemies) | |
{ | |
CanSpawnEnemies = canSpawnEnemies; | |
} | |
public void RemoveAllEnemies() | |
{ | |
if (levelBoss != null) | |
{ | |
Destroy(levelBoss); | |
} | |
if (levelEnemies != null) | |
{ | |
foreach (GameObject enemy in levelEnemies) | |
{ | |
Destroy(enemy); | |
} | |
} | |
levelBoss = null; | |
levelEnemies = new List<GameObject>(); | |
} | |
public void RespawnAllEnemies() | |
{ | |
SpawnEnemies(); | |
} | |
public void HideCursor(bool isCursorHidden) | |
{ | |
Cursor.visible = !isCursorHidden; | |
} | |
public void ResetZoomCamera() | |
{ | |
gameCamera.Cam.orthographicSize = gameCamera.DefaultSize; | |
} | |
public void HidePauseMenu(bool isPauseMenuHidden) | |
{ | |
if (isPauseMenuHidden) | |
{ | |
pauseMenuCanvasGroup.alpha = 0; | |
pauseMenuCanvasGroup.interactable = false; | |
} | |
else | |
{ | |
pauseMenuCanvasGroup.alpha = 1; | |
pauseMenuCanvasGroup.interactable = true; | |
} | |
} | |
public void ShowPlayerStats(bool isPlayerStatsActive) | |
{ | |
playerStatsCanvas.gameObject.SetActive(isPlayerStatsActive); | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment