Forum begins after the advertisement:


[General] Death Scene doesn’t deactive and after resume error

Home Forums Video Game Tutorial Series Creating a Metroidvania in Unity [General] Death Scene doesn’t deactive and after resume error

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #16558
    pepecry
    Level 7
    Participant
    Helpful?
    Up
    0
    ::

    When I testing the function, I figure out some errors even though it wasn’t there before. Firstly is the deathscene doesn’t deactive. When my player die and i click the respawn button, the scene reload and the player get respawn. But the problem is the deathscene doesn’t deactive as you can see in the two below image

    death scene after respawn console log Then i pause the game to check is the gamemanager is disable or not and the game manager still there Hierachy And I found another bug that when I press escape to pause the game, then click on resume or quit to main menu, it button still work good, but if i start the game again by click the start at the main menu, then pause the game using esc. And at the second time click on resume, my character got free and cannot moving. It kinda hard to explain so I will record it you could see it below
    Hierachy structure Game Manager prefabs Canvas Prefab Here the code relevant Respawn player controller code
    <code>public void Respawn()
    {
        if (!playerStateList.alive)
        {
            rbd2.constraints = RigidbodyConstraints2D.None;
            rbd2.constraints = RigidbodyConstraints2D.FreezeRotation;
            GetComponent<BoxCollider2D>().enabled = true;
            playerStateList.alive = true;
            Health = MaxHealth;
            Mana = 0;
            animator.Play("PlayerIdle");
    
        }
    }
    </code>

    Game Manager Code

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Cinemachine;
    using UnityEngine.SceneManagement;
    using UnityEngine.EventSystems;
    
    public class GameManager : MonoBehaviour
    {
        // Start is called before the first frame update
        public string transitionFromScene;
        public static GameManager Instance {  get; private set; }
    
        public Vector2 respawnpoint;
        [SerializeField] Alter alter;
        [SerializeField] private fadedUI pauseMenu;
        [SerializeField] private float fadeTime;
        public bool gameIsPause;
        public Vector2 platformRespawnpoint;
        private void Awake()
        {
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else 
            {
                Instance = this;
            }
            DontDestroyOnLoad(gameObject);
            alter = FindObjectOfType<Alter>();
        }
        private void Update()
        {
            if(Input.GetKeyDown(KeyCode.P))
            {
                SaveData.Instance.savePlayerData();
            }
            if (Input.GetKeyDown(KeyCode.Escape) && !gameIsPause)
            {
                pauseMenu.fadeUIIn(fadeTime);
                Time.timeScale = 0;
                gameIsPause = true;
            }
        }
    
        public void UnpauseGame()
        {
            Time.timeScale = 1;
            pauseMenu.fadeUIOut(fadeTime);
            gameIsPause = false;
        }
    
        public void SaveGame()
        {
            SaveData.Instance.savePlayerData();
        }
    
        public void respawnPlayer()
        {
            SaveData.Instance.loadAlter();
            if(SaveData.Instance.altersceneName != null)
            {
                SceneManager.LoadScene(SaveData.Instance.altersceneName);
            }
            if(SaveData.Instance.alterPos != null)
            {
    
                respawnpoint = SaveData.Instance.alterPos;
    
            }
            else
            {
                respawnpoint = platformRespawnpoint;
            }
            Move.Instance.transform.position = respawnpoint;
            StartCoroutine(UIManager.Instance.DeactiveDeathScreen());
            Move.Instance.Respawn();
        }
    
    
    }
    </code>

    UIManager Code

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class UIManager : MonoBehaviour
    {
        // Start is called before the first frame update
        public static UIManager Instance;
    
        [SerializeField] GameObject DeathSceen;
        public GameObject mapHandler;
        public GameObject inventory;
        private void Awake()
        {
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
            DontDestroyOnLoad(gameObject.transform.root.gameObject);
        }
    
        public SceneFading sceneFading;
        public void Start()
        {
            sceneFading = GetComponentInChildren<SceneFading>();
        }
    
        public IEnumerator ActiveDeathScreen()
        {
            yield return new WaitForSeconds(0.8f);
            StartCoroutine(sceneFading.Fade(SceneFading.fadeDirection.In));
            yield return new WaitForSeconds(0.9f);
            DeathSceen.SetActive(true);
        }
    
        public IEnumerator DeactiveDeathScreen()
        {
            yield return new WaitForSeconds(0.5f);
            DeathSceen.SetActive(false);
            StartCoroutine(sceneFading.Fade(SceneFading.fadeDirection.Out));
        }
    }
    </code>
    #16561
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    Your issue seems to arise from this error here:

    Null Reference Exception

    Are you able to figure out what is causing your GameManager to be disabled? Search for your scripts using the Command Prompt. Navigate to your project folder, then use findstr /s /c:"SetActive" *.cs to find all the scripts that deactivate a GameObject. Look for a script that deactivates your GameManager — you may have one that is unintentionally disabling your GameManager, causing the Coroutine to not run and everything else to fail.

    May I also know which part of the tutorial you are at?

    #16563
    pepecry
    Level 7
    Participant
    Helpful?
    Up
    0
    ::

    COuld said i was in part 10.5 of the series. Before of that when i’m at the part 9 and 9,5. The UI and death scene when i’m testing is still good and for the Error, here is what it found

    setactive found But i don’t seem anything look like it making disable the gamemanager. If yes so i think it is the one in the textdescription for the item. But when i check the item description, it only have this
    <code>public class itemDescription : MonoBehaviour
    {
        public GameObject textDesc;
        // Start is called before the first frame update
        void Start()
        {
            textDesc.SetActive(false);
        }
    
        // Update is called once per frame
        public void Show()
        {
            textDesc.SetActive(true);
        }
        public void Hide()
        {
            textDesc.SetActive(false);
        }
    }</code>

    should I tried by searching for the gamemanager?

    #16565
    A_DONUT
    Level 6
    Moderator
    Helpful?
    Up
    1
    ::

    It seems like you’re encountering two main issues: the death screen not deactivating after respawning, and the character getting stuck after pausing and resuming the game. Let’s break these down and troubleshoot each one step by step.


    Issue 1: Death Screen Not Deactivating After Respawn

    Possible Cause:

    • The DeathScreen GameObject might not be properly deactivated due to either:
      • The coroutine not being executed correctly.
      • A timing issue causing the coroutine to complete before the respawn logic finalizes.

    Solutions:

    1. Check Coroutine Execution: Ensure that the StartCoroutine(UIManager.Instance.DeactiveDeathScreen()); call in respawnPlayer() is actually being invoked. Add a debug log to confirm:

      public IEnumerator DeactiveDeathScreen()
      {
          Debug.Log("Deactivating Death Screen..."); // Add this line
          yield return new WaitForSeconds(0.5f);
          DeathSceen.SetActive(false);
          StartCoroutine(sceneFading.Fade(SceneFading.fadeDirection.Out));
      }
    2. Ensure DeathSceen is Referenced Correctly: Confirm that the DeathSceen variable in UIManager is assigned properly in the Inspector.

    3. Manual Deactivation Check: If the coroutine timing isn’t critical, try manually setting the death screen inactive right before starting the coroutine:

      public void respawnPlayer()
      {
          DeathSceen.SetActive(false); // Ensure it's off immediately
          StartCoroutine(UIManager.Instance.DeactiveDeathScreen());
          Move.Instance.Respawn();
      }
    4. Confirm Scene Reload Logic: If the GameManager object isn’t being destroyed on reload (due to DontDestroyOnLoad), make sure the DeathSceen is reset between scenes.


    Issue 2: Player Cannot Move After Resuming the Game

    Possible Cause:

    • When you pause and then resume, something might not be resetting Time.timeScale or the player’s movement constraints correctly.
    • The player’s movement script might be getting disabled or frozen unintentionally.

    Solutions:

    1. Check Time Scale Reset: Ensure Time.timeScale is set to 1 every time the game resumes:

      public void UnpauseGame()
      {
          Time.timeScale = 1;
          pauseMenu.fadeUIOut(fadeTime);
          gameIsPause = false;
          Debug.Log("Game unpaused, Time.timeScale reset to 1"); // Confirm reset
      }
    2. Reset Movement Constraints: After unpausing, check if the player’s Rigidbody constraints are correct:

      public void UnpauseGame()
      {
          Time.timeScale = 1;
          pauseMenu.fadeUIOut(fadeTime);
          gameIsPause = false;
      
          // Ensure the Rigidbody isn't constrained
          Rigidbody2D rbd2 = Move.Instance.GetComponent<Rigidbody2D>();
          rbd2.constraints = RigidbodyConstraints2D.FreezeRotation;
      }
    3. Check Player Controller State: Verify that the player’s movement script isn’t being disabled during pause and that it correctly resumes:

      if (Input.GetKeyDown(KeyCode.Escape) && !gameIsPause)
      {
          // Save movement state if needed
          pauseMenu.fadeUIIn(fadeTime);
          Time.timeScale = 0;
          gameIsPause = true;
      }
    4. Check if Movement Input is Blocked: There might be a condition in your movement code that prevents inputs when the game resumes. Ensure that all relevant flags are reset:

      void Update()
      {
          if (!gameIsPause && playerStateList.alive)
          {
              HandleMovement(); // Only handle movement if unpaused
          }
      }

    Debugging Recommendations:

    • Debug Logs: Use logs inside critical functions (Respawn(), UnpauseGame(), and DeactiveDeathScreen()) to track if they are called in the correct sequence.
    • Pause Flow Testing: Manually step through the pause and resume process in the Unity Editor while observing variable states in the Inspector (e.g., Time.timeScale, playerStateList.alive).

    This structured debugging approach should help you identify and fix the issues effectively!

    It seems like the GameManager issue might not directly involve this itemDescription script. Let’s approach this step by step to locate any unexpected SetActive(false) calls affecting the GameManager or DeathScreen.

    1. Search for SetActive(false) Calls in Your Project

    • Search in Unity:

      • In the Unity Editor, use the search bar in the Project window and search for SetActive(false). This will list all instances of the method in your scripts.
      • Look for any instances where the GameManager or DeathScreen might be inadvertently disabled.
    • Check in Code:
      Go through the search results and see if any of them reference the GameManager or other key objects. Pay special attention to:

      • Scripts that are supposed to control UI elements (like DeathScreen or pauseMenu).
      • Code related to respawning, pausing, or reloading scenes.

    2. Verify GameManager’s Active State

    Add a debug check to ensure GameManager stays active during critical moments:

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape) && !gameIsPause)
        {
            Debug.Log("Pausing game. GameManager active: " + this.gameObject.activeSelf);
            pauseMenu.fadeUIIn(fadeTime);
            Time.timeScale = 0;
            gameIsPause = true;
        }
    }

    If GameManager gets deactivated unexpectedly, this will help you catch it.


    3. Check the Death Screen Logic

    • Ensure no script disables GameManager or the DeathScreen GameObject after respawn.
    • Look for any logic that might hide the entire UI instead of just the death screen panel:
      DeathScreen.SetActive(false); // Should only affect the death screen, not the whole UI

    4. Ensure the Scene Reload Logic is Correct

    • Since GameManager uses DontDestroyOnLoad, it shouldn’t be affected by scene reloads. But if there’s logic explicitly reloading GameManager, it might cause problems.
    • Confirm that the respawnPlayer() function doesn’t unintentionally reload the GameManager.

    5. Isolate the Problem with Manual Checks

    • Temporarily disable parts of the code related to UI activation/deactivation and see if the DeathScreen still behaves the same way.
    • For instance, comment out the coroutine in respawnPlayer():
      // StartCoroutine(UIManager.Instance.DeactiveDeathScreen());
      DeathScreen.SetActive(false);  // Directly deactivate for testing

    6. Additional Debugging:

    • Breakpoints: Use breakpoints in the Visual Studio debugger on the SetActive() calls to see when and why they are triggered.
    • Logging: Add logs in your itemDescription class to ensure textDesc activation/deactivation doesn’t affect other objects:
      public void Show()
      {
          Debug.Log("Showing item description.");
          textDesc.SetActive(true);
      }

    By carefully searching for SetActive(false) calls and adding debug checks, you should be able to pinpoint where the issue lies. Let me know if you need help analyzing any specific code fragments you find!

    has upvoted this post.
    #16579
    pepecry
    Level 7
    Participant
    Helpful?
    Up
    1
    ::

    So as your recommend. I add this code in to the deactiveDeathsceen in UIManager

    <code>public IEnumerator DeactiveDeathScreen()
    {
        Debug.Log("Deactivating Death Screen…");
        yield return new WaitForSeconds(0.5f);
        DeathSceen.SetActive(false);
        StartCoroutine(sceneFading.Fade(SceneFading.fadeDirection.Out));
    }</code>

    and then tried it, well we could said the problem was here, this is what the console print out

    console And fot the checking the UIManager assign, i could confirm that i had assign it correct you could see 2 pictures below Canvas UIManager in Hierachy The first image is the canvas UIManager in the hierachy. And the second one is the canvas UIManager in the Prefab setting UIManager in Prefabs setting For the third recommend, it hard to do because the DeathSceen is the gameobject in the UI Manager as you could see below DeathSceen and the respawn was in the GameManager script so how could i call it to? and for the last recommend, it could be see here in this record Record for checking GameManager For the resume button, I would check it later
    has upvoted this post.
    #16585
    pepecry
    Level 7
    Participant
    Helpful?
    Up
    0
    ::

    So I just made another search in the unity editor and the result doesn’t look good. There is no any SetActive(false); was disable the game manager intentionally. I looking for the DeathSceen but still there is only 2 place where DeathSceen was call is in ActiveDeathSceen and DeactiveDeathSceen And for the resume error. I added the code like you said

    private void Update()
     {
         if(Input.GetKeyDown(KeyCode.P))
         {
             SaveData.Instance.savePlayerData();
         }
         if (Input.GetKeyDown(KeyCode.Escape) && !gameIsPause)
         {
             pauseMenu.fadeUIIn(fadeTime);
             Debug.Log("Pausing game. GameManager active: " + this.gameObject.activeSelf);
             Time.timeScale = 0;
             gameIsPause = true;
         }
     }
    
     public void UnpauseGame()
     {
         Time.timeScale = 1; 
         pauseMenu.fadeUIOut(fadeTime); 
         gameIsPause = false;
         Rigidbody2D rbd2 = Move.Instance.GetComponent<Rigidbody2D>();
         rbd2.constraints = RigidbodyConstraints2D.FreezeRotation;
         Debug.Log("Game unpaused, Time.timeScale reset to 1");
     }

    But the game only reply by this message and the null ref

    Console And my character still cannot take input. Below of the controller doesn’t have any information about the game mananger or the pause. I checked it all
    #16600
    pepecry
    Level 7
    Participant
    Helpful?
    Up
    2
    ::

    I found out the fix way (or we could said it like that). The reason is because of the Unity itself. I watch back some topic before and when i check the topic of MI NI. This guy said he has fix it by just delete the action of the button and then add it again. I tried it and then it work. Really work. For both the problem is the deathsceen doesn’t deactive and the pausemenu making game doesn’t taking input anymore. Tks you guys alot and especially thanks to Mi Ni

    and 1 other person have upvoted this post.
    #16605
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    Glad you managed to fix this Pepe

Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: