Forum begins after the advertisement:
[Part 27] Missing adjustments in “GameManager.cs”
Home › Forums › Video Game Tutorial Series › Creating a Rogue-like Shoot-em Up in Unity › [Part 27] Missing adjustments in “GameManager.cs”
- This topic has 9 replies, 3 voices, and was last updated 1 week ago by
Terence.
-
AuthorPosts
-
August 17, 2025 at 11:21 pm #18639::
In the “UITreasureChest.cs” at line 105 there is a reference to the GameManger.cs, but the GameState “TreasureChest” is missing.
GameManager.instance.ChangeState(GameManager.GameState.TreasureChest);
The Question is what has to be added in the GameManger.cs, is this enough?
public enum GameState { Gameplay, Paused, GameOver, Success, LevelUp, TreasureChest }
August 17, 2025 at 11:29 pm #18640August 18, 2025 at 1:27 am #18648::The problem seems not to be fixed! Whenever I enter a treasure chest the game won’t pause, the Treasure Chest button “open” isn’t clickable and I get multiple Debug errors claiming “STATE DOES NOT EXIST”. I guess we still have to define the State “TreasureChest” in the GameManager.cs, right?
August 18, 2025 at 1:32 am #18649August 18, 2025 at 1:40 am #18654::It looks like you’ve already added the
TreasureChest
state to yourGameState
enum, which is a good first step. However, it’s also important to ensure that the state is properly handled in theGameManager
class. Here are a few steps you might need to take to fully implement this state:-
Implement State Change Logic: Ensure that you have logic in your
GameManager
class to handle what happens when theTreasureChest
state is entered. This might involve pausing the game and showing the treasure chest UI.Example:
public void ChangeState(GameState newState) { // Handle exiting the current state if needed switch (currentState) { case GameState.Gameplay: // Logic to exit Gameplay state break; case GameState.TreasureChest: // Logic to exit TreasureChest state break; // Handle other states } currentState = newState; // Handle entering the new state switch (newState) { case GameState.Gameplay: // Logic to enter Gameplay state break; case GameState.TreasureChest: // Logic to enter TreasureChest state PauseGame(); // Example of pausing the game ShowTreasureChestUI(); // Show the UI for the treasure chest break; // Handle other states } }
-
Pause Game Logic: If the game is not pausing when you enter the
TreasureChest
state, make sure that thePauseGame()
method (or whatever you are using) is correctly implemented. -
UI Interaction: Ensure that the UI elements related to the treasure chest are enabled and properly set up. If the button isn’t clickable, check if it is being disabled somewhere in your code or if there are any graphical layers blocking it.
-
Debugging State Errors: If you are getting errors claiming “STATE DOES NOT EXIST”, double-check that you are referencing the state correctly throughout your code. Also, look for any places where you might be trying to access a state that hasn’t been fully implemented.
-
Testing: Finally, you can add debug logs in your
ChangeState
method to see the flow of state changes, which can help identify where things might be going wrong.
Here’s an example of adding debug logs:
public void ChangeState(GameState newState) { Debug.Log($"Changing state from {currentState} to {newState}"); // ... rest of your state change logic }
By following these steps, you should be able to ensure that the
TreasureChest
state is implemented correctly and that the game behaves as expected when entering this state. If you continue to face issues, please provide more details about yourGameManager
implementation, and I can help further!August 18, 2025 at 2:03 am #18656::I think the problem is, that there should be a definition of what to do when “GameState.TreasureChest” is active. At the moment nothing is defined here:
switch (currentState) { case GameState.Gameplay: // Code for the gameplay state CheckForPauseAndResume(); UpdateStopwatch(); CheckForBuffs(); break; case GameState.Paused: // Code for the paused state CheckForPauseAndResume(); break; case GameState.GameOver: case GameState.Success: case GameState.LevelUp: case GameState.TreasureChest: // Logic to enter TreasureChest state XXXXXXXX break; default: Debug.LogWarning("STATE DOES NOT EXIST"); break; }
August 18, 2025 at 2:05 am #18657::Based on the reference information and the context provided, here’s a suggested implementation for the
GameState.TreasureChest
case:case GameState.TreasureChest: Time.timeScale = 0f; // Pause the game CheckForPauseAndResume(); // Allow potential resume functionality break;
This implementation follows the pattern seen in other game states like
Paused
andGameOver
, where:- The game time is stopped using
Time.timeScale = 0f
- The
CheckForPauseAndResume()
method is called to maintain consistent pause/resume behavior - It prevents game logic from updating while in the treasure chest state
August 18, 2025 at 2:30 am #18658::This is my current GameManager.cs (I only added “TreasureChest” in the public enum GameState. The question is, what should happen when the GameState “TreasureChest” is active? What about the “UITreasureChest.cs” in this GameState?
using System.Collections; using UnityEngine; using UnityEngine.UI; using TMPro; public class GameManager : MonoBehaviour { public static GameManager instance; // Define the different states of the game public enum GameState { Gameplay, Paused, Craft, Shop, GameOver, Success, LevelUp, TreasureChest } // Store the current state of the game public GameState currentState; // Store the previous state of the game before it was paused public GameState previousState; [Header("Damage Text Settings")] public Canvas damageTextCanvas; public float textFontSize = 20; public TMP_FontAsset textFont; public Camera referenceCamera; public Image BossHealthBar; [Header("Screens")] public GameObject pauseScreen; public GameObject resultsScreen; public GameObject successScreen; public GameObject craftScreen; public GameObject shopScreen; public GameObject levelUpScreen; int stackedLevelUps = 0; // If we try to StartLevelUp() multiple times. [Header("Results Screen Displays")] public Image chosenCharacterImage; public Image chosenCharacterImagePause; public Image chosenCharacterImageCraft; public Image chosenCharacterImageShop; public Image chosenCharacterImageUpgrade; public TMP_Text chosenCharacterName; public TMP_Text chosenCharacterNamePause; public TMP_Text chosenCharacterNameCraft; public TMP_Text chosenCharacterNameShop; public TMP_Text chosenCharacterNameUpgrade; public TMP_Text levelReachedDisplay; public TMP_Text timeSurvivedDisplay; [Header("Stopwatch")] public float timeLimit; // The time limit in seconds float stopwatchTime; // The current time elapsed since the stopwatch started public TMP_Text stopwatchDisplay; [Header("Music")] public GameObject BackgroundMusic; public GameObject BackgroundMusicBoss; public GameObject DeathMusic; public GameObject EndMusic; [Header("Boss Health Bar and Message")] public GameObject bosshealthBar; public GameObject bosskilledInfo; [Header("Cheats and Log")] public GameObject cheatStuff; PlayerStats[] players; // Tracks all players. // Getters for parity with older scripts. public bool isGameOver { get { return currentState == GameState.Paused; } } public bool isSuccess { get { return currentState == GameState.Paused; } } public bool isShop { get { return currentState == GameState.Shop; } } public bool isCraft { get { return currentState == GameState.Craft; } } public bool choosingUpgrade { get { return currentState == GameState.LevelUp; } } // Gives us the time since the level has started. public float GetElapsedTime() { return stopwatchTime; } // Sums up the curse stat of all players and returns the value. public static float GetCumulativeCurse() { if (!instance) return 1; float totalCurse = 0; foreach (PlayerStats p in instance.players) { totalCurse += p.Actual.curse; } return Mathf.Max(1, totalCurse); } // Sum up the levels of all players and returns the value. public static int GetCumulativeLevels() { if (!instance) return 1; int totalLevel = 0; foreach (PlayerStats p in instance.players) { totalLevel += p.level; } return Mathf.Max(1, totalLevel); } void Awake() { players = FindObjectsOfType<PlayerStats>(); //Warning check to see if there is another singleton of this kind already in the game if (instance == null) { instance = this; } else { Debug.LogWarning("EXTRA " + this + " DELETED"); Destroy(gameObject); } DisableScreens(); } void Update() { // Toggle Cheats on/off if (Input.GetKeyDown("0")) { cheatStuff.SetActive(!cheatStuff.activeInHierarchy); } switch (currentState) { case GameState.Gameplay: // Code for the gameplay state CheckForPauseAndResume(); UpdateStopwatch(); break; case GameState.Paused: // Code for the paused state CheckForPauseAndResume(); break; case GameState.GameOver: case GameState.Success: case GameState.Craft: case GameState.Shop: case GameState.LevelUp: break; default: Debug.LogWarning("STATE DOES NOT EXIST"); break; } } IEnumerator GenerateFloatingTextCoroutine(string text, Transform target, float duration = 1f, float speed = 100f) { // Start generating the floating text. GameObject textObj = new GameObject("Damage Floating Text"); RectTransform rect = textObj.AddComponent<RectTransform>(); TextMeshProUGUI tmPro = textObj.AddComponent<TextMeshProUGUI>(); tmPro.text = text; tmPro.horizontalAlignment = HorizontalAlignmentOptions.Center; tmPro.verticalAlignment = VerticalAlignmentOptions.Middle; tmPro.fontSize = textFontSize; if (textFont) tmPro.font = textFont; rect.position = referenceCamera.WorldToScreenPoint(target.position); // Makes sure this is destroyed after the duration finishes. Destroy(textObj, duration); // Parent the generated text object to the canvas. textObj.transform.SetParent(instance.damageTextCanvas.transform); textObj.transform.SetSiblingIndex(0); // Pan the text upwards and fade it away over time. WaitForEndOfFrame w = new WaitForEndOfFrame(); float t = 0; float yOffset = 0; Vector3 lastKnownPosition = target.position; while (t < duration) { // If the RectTransform is missing for whatever reason, end this loop. if (!rect) break; // Fade the text to the right alpha value. tmPro.color = new Color(tmPro.color.r, tmPro.color.g, tmPro.color.b, 1 - t / duration); // Update the enemy's position if it is still around. if (target) lastKnownPosition = target.position; // Pan the text upwards. yOffset += speed * Time.deltaTime; rect.position = referenceCamera.WorldToScreenPoint(lastKnownPosition + new Vector3(0, yOffset)); // Wait for a frame and update the time. yield return w; t += Time.deltaTime; } } public static void GenerateFloatingText(string text, Transform target, float duration = 1f, float speed = 1f) { // If the canvas is not set, end the function so we don't // generate any floating text. if (!instance.damageTextCanvas) return; // Find a relevant camera that we can use to convert the world // position to a screen position. if (!instance.referenceCamera) instance.referenceCamera = Camera.main; instance.StartCoroutine(instance.GenerateFloatingTextCoroutine( text, target, duration, speed )); } // Define the method to change the state of the game public void ChangeState(GameState newState) { previousState = currentState; currentState = newState; } //public GameObject otherobj;//your other object //public string scr;// your secound script name public void Shop() { if (currentState != GameState.Shop) { ChangeState(GameState.Shop); Time.timeScale = 0f; // Stop the game BackgroundMusic.SetActive(false); shopScreen.SetActive(true); // Enable the shop screen FindObjectOfType<ShowResources>().Show(); FindObjectOfType<Shop>().ShopText(); FindObjectOfType<Shop>().getShopItems(); FindObjectOfType<PlayerStats>().showDamageStats(); } } public void CloseShop() { if (currentState == GameState.Shop) { ChangeState(previousState); Time.timeScale = 1f; // Stop the game BackgroundMusic.SetActive(true); //(otherobj.GetComponent(scr) as MonoBehaviour).enabled = false; FindObjectOfType<ShowResources>().Hide(); shopScreen.SetActive(false); // Disable the shop screen } } public void Craft() { if (currentState != GameState.Craft) { ChangeState(GameState.Craft); Time.timeScale = 0f; // Stop the game BackgroundMusic.SetActive(false); craftScreen.SetActive(true); // Enable the craft screen FindObjectOfType<Crafting>().getCraftItems(); FindObjectOfType<ShowResources>().Show(); FindObjectOfType<PlayerStats>().showDamageStats(); //AudioListener.pause = true; } } public void CloseCraft() { if (currentState == GameState.Craft) { ChangeState(previousState); Time.timeScale = 1f; // Stop the game BackgroundMusic.SetActive(true); FindObjectOfType<ShowResources>().Hide(); craftScreen.SetActive(false); // Disable the craft screen //AudioListener.pause = false; } } public void PauseGame() { if (currentState != GameState.Paused) { ChangeState(GameState.Paused); Time.timeScale = 0f; // Stop the game pauseScreen.SetActive(true); // Enable the pause screen FindObjectOfType<ShowResources>().Show(); FindObjectOfType<PlayerStats>().showDamageStats(); AudioListener.pause = true; } } public void ResumeGame() { if (currentState == GameState.Paused) { ChangeState(previousState); Time.timeScale = 1f; // Resume the game pauseScreen.SetActive(false); //Disable the pause screen FindObjectOfType<ShowResources>().Hide(); AudioListener.pause = false; } } // Define the method to check for pause and resume input void CheckForPauseAndResume() { if (Input.GetKeyDown(KeyCode.Escape)) { if (currentState == GameState.Paused) { ResumeGame(); } else { PauseGame(); } } } void DisableScreens() { pauseScreen.SetActive(false); resultsScreen.SetActive(false); successScreen.SetActive(false); shopScreen.SetActive(false); craftScreen.SetActive(false); levelUpScreen.SetActive(false); } public void GameOver() { timeSurvivedDisplay.text = stopwatchDisplay.text; // Set the Game Over variables here. ChangeState(GameState.GameOver); Time.timeScale = 0f; //Stop the game entirely DisplayResults(); FindObjectOfType<ShowResources>().Show(); BackgroundMusic.SetActive(false); BackgroundMusicBoss.SetActive(false); DeathMusic.SetActive(true); } public void Success() { StartCoroutine(SuccessEnding()); } IEnumerator SuccessEnding() { timeSurvivedDisplay.text = stopwatchDisplay.text; bosshealthBar.SetActive(false); bosskilledInfo.SetActive(true); yield return new WaitForSeconds(5); // Set the Success variables here. ChangeState(GameState.Success); Time.timeScale = 0f; //Stop the game entirely DisplaySuccess(); FindObjectOfType<ShowResources>().Show(); BackgroundMusic.SetActive(false); BackgroundMusicBoss.SetActive(false); EndMusic.SetActive(true); } void DisplaySuccess() { successScreen.SetActive(true); } void DisplayResults() { resultsScreen.SetActive(true); } public void AssignChosenCharacterUI(CharacterData chosenCharacterData) { chosenCharacterImage.sprite = chosenCharacterImagePause.sprite = chosenCharacterImageShop.sprite = chosenCharacterImageCraft.sprite = chosenCharacterImageUpgrade.sprite = chosenCharacterData.Icon; chosenCharacterName.text = chosenCharacterNamePause.text = chosenCharacterNameShop.text = chosenCharacterNameCraft.text = chosenCharacterNameUpgrade.text = chosenCharacterData.FullName; } public void AssignLevelReachedUI(int levelReachedData) { levelReachedDisplay.text = levelReachedData.ToString(); } void UpdateStopwatch() { stopwatchTime += Time.deltaTime; UpdateStopwatchDisplay(); if (stopwatchTime >= timeLimit) { foreach (PlayerStats p in players) p.SendMessage("GAME ENDS"); } } void UpdateStopwatchDisplay() { // Calculate the number of minutes and seconds that have elapsed int minutes = Mathf.FloorToInt(stopwatchTime / 60); int seconds = Mathf.FloorToInt(stopwatchTime % 60); // Update the stopwatch text to display the elapsed time stopwatchDisplay.text = string.Format("{0:00}:{1:00}", minutes, seconds); } public void StartLevelUp() { ChangeState(GameState.LevelUp); // If the level up screen is already active, record it. if (levelUpScreen.activeSelf) stackedLevelUps++; else { levelUpScreen.SetActive(true); FindObjectOfType<ShowResources>().Show(); Time.timeScale = 0f; //Pause the game for now foreach (PlayerStats p in players) p.SendMessage("RemoveAndApplyUpgrades"); } } public void EndLevelUp() { Time.timeScale = 1f; //Resume the game levelUpScreen.SetActive(false); FindObjectOfType<ShowResources>().Hide(); ChangeState(GameState.Gameplay); // Increase Insight +1 FindObjectOfType<PlayerStats>().IncreaseInsight(1); if (stackedLevelUps > 0) { stackedLevelUps--; StartLevelUp(); } } }
August 18, 2025 at 2:35 am #18659::Based on the existing pattern in the GameManager.cs, here’s how you should handle the TreasureChest state:
- In the
Update()
method, add a case forGameState.TreasureChest
:
case GameState.TreasureChest: CheckForPauseAndResume(); break;
- Add a method similar to other state-specific methods like
Shop()
andCraft()
:
public void OpenTreasureChest() { if (currentState != GameState.TreasureChest) { ChangeState(GameState.TreasureChest); Time.timeScale = 0f; // Stop the game // Activate treasure chest UI // You'll need to add a treasureChestScreen to your [Header("Screens")] section treasureChestScreen.SetActive(true); FindObjectOfType().Show(); } } public void CloseTreasureChest() { if (currentState == GameState.TreasureChest) { ChangeState(previousState); Time.timeScale = 1f; // Resume the game treasureChestScreen.SetActive(false); FindObjectOfType().Hide(); } }
- Update the
DisableScreens()
method to include the treasure chest screen:
void DisableScreens() { // ... existing code ... treasureChestScreen.SetActive(false); }
Would you like me to elaborate on any of these points or clarify anything about implementing the TreasureChest state?
August 18, 2025 at 2:44 am #18661::@Terence This seems a little odd, can you confirm that these adjustments in the “GameManger.cs” are effective?
August 18, 2025 at 2:45 am #18663::The adjustments I suggested for handling the
GameState.TreasureChest
should indeed be effective if implemented correctly. To summarize and clarify:-
State Management: You added the
TreasureChest
case in theUpdate()
method, which allows the game to check for pause and resume functionality while the treasure chest state is active. -
Open and Close Methods: The
OpenTreasureChest()
andCloseTreasureChest()
methods will manage transitioning to and from theTreasureChest
state. These methods ensure that:- When opening the treasure chest, the game pauses, and the treasure chest UI is shown.
- When closing the treasure chest, it resumes the previous game state and hides the UI.
-
Disable Screens: By updating the
DisableScreens()
method to include the treasure chest screen, you ensure that the UI is appropriately managed when switching states.
Checklist for Effectiveness:
- UI Activation: Ensure that you have a GameObject for the
treasureChestScreen
and that it’s referenced correctly in yourGameManager
. - Testing: After implementing these changes, test the following:
- Entering a treasure chest pauses the game.
- The treasure chest UI appears and is interactive.
- Closing the treasure chest resumes the previous game state and hides the UI.
Debugging:
If you encounter any issues:
- Add debug logs in the
OpenTreasureChest()
andCloseTreasureChest()
methods to confirm they are being called. - Check for any errors in the console that may indicate issues with UI elements or state transitions.
If everything is set up correctly, these adjustments should work effectively to manage the treasure chest state within your game. If you still run into issues, please let me know, and we can troubleshoot further!
August 18, 2025 at 12:59 pm #18677::@Terence This seems a little odd, can you confirm that these adjustments in the “GameManger.cs” are effective?
Grim, you’re right. You should only need the highlighted portion below after adding
TreasureChest
to theGameState
enum:void Update() { switch (currentState) { case GameState.Gameplay: // Code for the gameplay state Time.timeScale = 1.0f; CheckForPauseAndResume(); UpdateStopwatch(); break; case GameState.Paused: // Code for the paused state CheckForPauseAndResume(); break; case GameState.GameOver: case GameState.TreasureChest: Time.timeScale = 0; break; case GameState.LevelUp: break; default: Debug.LogWarning("STATE DOES NOT EXIST"); break; } }
It shares the same state logic as
GameOver
.August 18, 2025 at 3:36 pm #18679August 21, 2025 at 4:38 pm #18747::There were also a couple of changes to Part 27’s project files that were not documented:
- Instead of having the Done button do the SaveCoinsToStash() (as we did in Part 26), we instead have the GameManager call it whenever GameOver() is triggered. This makes the action much easier to find, which makes debugging easier.
- Since the game time and clock speed is now determined by the level data that we key into the level select scene, we’ve also added a default value for both game time and clock speed that the GameManager defaults to.
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; public class GameManager : MonoBehaviour { public static GameManager instance; // Define the different states of the game public enum GameState { Gameplay, Paused, GameOver, LevelUp, TreasureChest } // Store the current state of the game public GameState currentState; // Store the previous state of the game before it was paused public GameState previousState; [Header("Damage Text Settings")] public Canvas damageTextCanvas; public float textFontSize = 20; public TMP_FontAsset textFont; public Camera referenceCamera; [Header("Screens")] public GameObject pauseScreen; public GameObject resultsScreen; public GameObject levelUpScreen; int stackedLevelUps = 0; // If we try to StartLevelUp() multiple times. [Header("Results Screen Displays")] public Image chosenCharacterImage; public TMP_Text chosenCharacterName; public TMP_Text levelReachedDisplay; public TMP_Text timeSurvivedDisplay; const float DEFAULT_TIME_LIMIT = 1800f; const float DEFAULT_CLOCK_SPEED = 1f; float ClockSpeed => UILevelSelector.currentLevel?.clockSpeed ?? DEFAULT_CLOCK_SPEED; float TimeLimit => UILevelSelector.currentLevel?.timeLimit ?? DEFAULT_TIME_LIMIT; [Header("Stopwatch")] public float timeLimit; // The time limit in seconds float stopwatchTime; // The current time elapsed since the stopwatch started public TMP_Text stopwatchDisplay; bool levelEnded = false; // Has the time limit been reached? public GameObject reaperPrefab; // Spawns after time limit has been reached; PlayerStats[] players; // Tracks all players. // Getters for parity with older scripts. public bool isGameOver { get { return currentState == GameState.Paused; } } public bool choosingUpgrade { get { return currentState == GameState.LevelUp; } } // Gives us the time since the level has started. public float GetElapsedTime() { return stopwatchTime; } // Sums up the curse stat of all players and returns the value. public static float GetCumulativeCurse() { if (!instance) return 1; float totalCurse = 0; foreach (PlayerStats p in instance.players) { totalCurse += p.Actual.curse; } return Mathf.Max(1, totalCurse); } // Sum up the levels of all players and returns the value. public static int GetCumulativeLevels() { if (!instance) return 1; int totalLevel = 0; foreach (PlayerStats p in instance.players) { totalLevel += p.level; } return Mathf.Max(1, totalLevel); } void Awake() { players = FindObjectsOfType<PlayerStats>(); //Set the level's Time Limit timeLimit =
UILevelSelector.currentLevel.timeLimitTimeLimit; //Warning check to see if there is another singleton of this kind already in the game if (instance == null) { instance = this; } else { Debug.LogWarning("EXTRA " + this + " DELETED"); Destroy(gameObject); } DisableScreens(); } void Update() { switch (currentState) { case GameState.Gameplay: // Code for the gameplay state Time.timeScale = 1; CheckForPauseAndResume(); UpdateStopwatch(); break; case GameState.Paused: // Code for the paused state CheckForPauseAndResume(); break; case GameState.GameOver: case GameState.TreasureChest: Time.timeScale = 0; break; case GameState.LevelUp: break; default: Debug.LogWarning("STATE DOES NOT EXIST"); break; } } IEnumerator GenerateFloatingTextCoroutine(string text, Transform target, float duration = 1f, float speed = 50f) { // Start generating the floating text. GameObject textObj = new GameObject("Damage Floating Text"); RectTransform rect = textObj.AddComponent<RectTransform>(); TextMeshProUGUI tmPro = textObj.AddComponent<TextMeshProUGUI>(); tmPro.text = text; tmPro.horizontalAlignment = HorizontalAlignmentOptions.Center; tmPro.verticalAlignment = VerticalAlignmentOptions.Middle; tmPro.fontSize = textFontSize; if (textFont) tmPro.font = textFont; rect.position = referenceCamera.WorldToScreenPoint(target.position); // Makes sure this is destroyed after the duration finishes. Destroy(textObj, duration); // Parent the generated text object to the canvas. textObj.transform.SetParent(instance.damageTextCanvas.transform); textObj.transform.SetSiblingIndex(0); // Pan the text upwards and fade it away over time. WaitForEndOfFrame w = new WaitForEndOfFrame(); float t = 0; float yOffset = 0; Vector3 lastKnownPosition = target.position; while (t < duration) { // If the RectTransform is missing for whatever reason, end this loop. if (!rect) break; // Fade the text to the right alpha value. tmPro.color = new Color(tmPro.color.r, tmPro.color.g, tmPro.color.b, 1 - t / duration); // Update the enemy's position if it is still around. if (target) lastKnownPosition = target.position; // Pan the text upwards. yOffset += speed * Time.deltaTime; rect.position = referenceCamera.WorldToScreenPoint(lastKnownPosition + new Vector3(0, yOffset)); // Wait for a frame and update the time. yield return w; t += Time.deltaTime; } } public static void GenerateFloatingText(string text, Transform target, float duration = 1f, float speed = 1f) { // If the canvas is not set, end the function so we don't // generate any floating text. if (!instance.damageTextCanvas) return; // Find a relevant camera that we can use to convert the world // position to a screen position. if (!instance.referenceCamera) instance.referenceCamera = Camera.main; instance.StartCoroutine(instance.GenerateFloatingTextCoroutine( text, target, duration, speed )); } // Define the method to change the state of the game public void ChangeState(GameState newState) { previousState = currentState; currentState = newState; } public void PauseGame() { if (currentState != GameState.Paused) { ChangeState(GameState.Paused); Time.timeScale = 0f; // Stop the game pauseScreen.SetActive(true); // Enable the pause screen } } public void ResumeGame() { if (currentState == GameState.Paused) { ChangeState(previousState); Time.timeScale = 1f; // Resume the game pauseScreen.SetActive(false); //Disable the pause screen } } // Define the method to check for pause and resume input void CheckForPauseAndResume() { if (Input.GetKeyDown(KeyCode.Escape)) { if (currentState == GameState.Paused) { ResumeGame(); } else { PauseGame(); } } } void DisableScreens() { pauseScreen.SetActive(false); resultsScreen.SetActive(false); levelUpScreen.SetActive(false); } public void GameOver() { timeSurvivedDisplay.text = stopwatchDisplay.text; // Set the Game Over variables here. ChangeState(GameState.GameOver); Time.timeScale = 0f; //Stop the game entirely DisplayResults(); // Save all the coins of all the players to the save file. foreach (PlayerStats p in players) { p.GetComponentInChildren<PlayerCollector>().SaveCoinsToStash(); } // Add all players' coins to their save file, since the game has ended. foreach(PlayerStats p in players) { if(p.TryGetComponent(out PlayerCollector c)) { c.SaveCoinsToStash(); } } } void DisplayResults() { resultsScreen.SetActive(true); } public void AssignChosenCharacterUI(CharacterData chosenCharacterData) { chosenCharacterImage.sprite = chosenCharacterData.Icon; chosenCharacterName.text = chosenCharacterData.Name; } public void AssignLevelReachedUI(int levelReachedData) { levelReachedDisplay.text = levelReachedData.ToString(); } public Vector2 GetRandomPlayerLocation() { int chosenPlayer = Random.Range(0, players.Length); return new Vector2(players[chosenPlayer].transform.position.x, players[chosenPlayer].transform.position.y); } void UpdateStopwatch() { stopwatchTime += Time.deltaTime * ClockSpeedUILevelSelector.currentLevel.clockSpeed; UpdateStopwatchDisplay(); if (stopwatchTime >= timeLimit && !levelEnded) { levelEnded = true; // Set the enemy/event spawner GameObject inactive to stop enemies from spawning and kill the remaining enemies onscreen. FindObjectOfType<SpawnManager>().gameObject.SetActive(false); foreach (EnemyStats e in FindObjectsOfType<EnemyStats>()) e.SendMessage("Kill"); // Spawn the Reaper off-camera Vector2 reaperOffset = Random.insideUnitCircle * 50f; Vector2 spawnPosition = GetRandomPlayerLocation() + reaperOffset; Instantiate(reaperPrefab, spawnPosition, Quaternion.identity); } } void UpdateStopwatchDisplay() { // Calculate the number of minutes and seconds that have elapsed int minutes = Mathf.FloorToInt(stopwatchTime / 60); int seconds = Mathf.FloorToInt(stopwatchTime % 60); // Update the stopwatch text to display the elapsed time stopwatchDisplay.text = string.Format("{0:00}:{1:00}", minutes, seconds); } public void StartLevelUp() { ChangeState(GameState.LevelUp); // If the level up screen is already active, record it. if (levelUpScreen.activeSelf) stackedLevelUps++; else { levelUpScreen.SetActive(true); Time.timeScale = 0f; //Pause the game for now foreach (PlayerStats p in players) p.SendMessage("RemoveAndApplyUpgrades"); } } public void EndLevelUp() { Time.timeScale = 1f; //Resume the game levelUpScreen.SetActive(false); ChangeState(GameState.Gameplay); if (stackedLevelUps > 0) { stackedLevelUps--; StartLevelUp(); } } } -
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: