Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question How do you add a delay to a victory scene?

Discussion in 'Community Learning & Teaching' started by Asough, May 18, 2024.

  1. Asough

    Asough

    Joined:
    Sep 12, 2022
    Posts:
    177
    I want my game to show a victory scene, after the player shoots an asteroid and destroys it. So I have created this script and attached it to the asteroid, and it works.

    Code (CSharp):
    1. public class Victory : MonoBehaviour
    2. {
    3.     public void OnDestroy ()
    4.     {
    5.             SceneManager.LoadScene("Victory");      
    6.     }
    7. }
    However, I also want to add a short delay of ten seconds before the game shows the victory scene, after the asteroid has been destroyed. I have tried all of the solutions that I could find and nothing works.

    The problem is that the asteroid gets destroyed, and then the victory scene pops up immediately afterwards.
     
    Last edited: May 22, 2024
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,391
  3. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,922
    Just food for thought, depends on the requirements but it's not strictly necessary to load a scene only to show something else, even fullscreen. You could also have the "victory" GUI in the current scene and just activate it. This will provide a faster response.
     
  4. Asough

    Asough

    Joined:
    Sep 12, 2022
    Posts:
    177
    This is the best I could do:

    Code (CSharp):
    1. public class Victory : MonoBehaviour
    2. {
    3.     IEnumerator NextLevelAfterWait()
    4.     {
    5.         yield return new WaitForSeconds(3.0f);
    6.  
    7.         SceneManager.LoadScene("Victory");
    8.     }
    9.  
    10.     public void OnDestroy()
    11.     {
    12.             StartCoroutine(NextLevelAfterWait());
    13.     }
    14. }
    It still doesn't work. It says coroutine couldn't be started because the game object 'Asteroid' is inactive!
     
    Last edited: May 22, 2024
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,391
    As per the docs, coroutines get stopped when the game object they were started from is destroyed or made inactive. Calling StartCoroutine in OnDestroy fails both these qualifiers.

    So you need to start the coroutine from a game object that is in neither of these states. If this component doesn't need to reference anything, then it could just create itself and then start the coroutine this way.

    Code (CSharp):
    1. public class Victory : MonoBehaviour
    2. {
    3.     IEnumerator NextLevelAfterWait()
    4.     {
    5.         yield return new WaitForSeconds(3.0f);
    6.         SceneManager.LoadScene("Victory");
    7.     }
    8.  
    9.     public void StartVictoryCoroutine()
    10.     {
    11.         StartCoroutine(NextLevelAfterWait());
    12.     }
    13.    
    14.     public static void StartVictory()
    15.     {
    16.         var victoryGameObject = new GameObject("Victory");
    17.         var victory = victoryGameObject.AddComponent<Victory>();
    18.         victory.StartVictoryCoroutine();
    19.     }
    20. }
    Then from anywhere else you can call
    Victory.StartVictory()
    .
     
  6. Asough

    Asough

    Joined:
    Sep 12, 2022
    Posts:
    177
    Thanks, but I'm still not sure if I get it? Do I just attach the script to basically any other game object in the game, and that's it?
     
  7. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,391
    No, as mentioned you can just call
    Victory.StartVictory();
    from anywhere and it will create an instance of itself.
     
  8. Asough

    Asough

    Joined:
    Sep 12, 2022
    Posts:
    177
    That works. I created the script, saved it and then I created this script and attached it to the asteroid:

    Code (CSharp):
    1. public class Destroy : MonoBehaviour
    2.  
    3.     public void OnDestroy()
    4.     {
    5.         Victory.StartVictory();
    6.     }
    It plays the victory scene now, after the asteroid has been destroyed.
     
    Last edited: May 22, 2024