Source file unity-csharp/scene-flow/GameOverTrigger.cs from the GDnD code examples. Download raw file

// GDnD wiki example
// Demonstrates: ending a level with a win or lose outcome from a 2D trigger, after a short delay
// Related pages: [[unity-scene-management]], [[unity-collider2d-and-triggers]]
 
using UnityEngine;
using UnityEngine.SceneManagement;
 
// Needs a Collider2D with Is Trigger ticked. The player needs the "Player" tag
// and a Rigidbody2D, otherwise OnTriggerEnter2D is never called.
[RequireComponent(typeof(Collider2D))]
public class GameOverTrigger : MonoBehaviour
{
    public enum Outcome { Lose, Win }
 
    [SerializeField] private Outcome outcome = Outcome.Lose;
    [SerializeField] private string loseSceneName = "GameOver";
    [SerializeField] private string winSceneName = "Win";
    [SerializeField] private float delaySeconds = 0.5f;
    [SerializeField] private SceneFlow sceneFlow;
 
    private bool hasFired;
 
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (hasFired || !other.CompareTag("Player"))
        {
            return;
        }
 
        hasFired = true; // stops two colliders or two frames ending the game twice
 
        if (GameSession.Instance != null)
        {
            GameSession.Instance.RecordResult(SceneManager.GetActiveScene().name, outcome == Outcome.Win);
        }
 
        // Invoke is widely reported to count scaled time, so it should wait while
        // Time.timeScale is 0 (the Scripting API page does not say; README step 5 tests it).
        Invoke(nameof(LoadEndScene), delaySeconds);
    }
 
    private void LoadEndScene()
    {
        if (sceneFlow == null)
        {
            Debug.LogError("GameOverTrigger on " + gameObject.name + " has no SceneFlow assigned.");
            return;
        }
 
        sceneFlow.LoadScene(outcome == Outcome.Win ? winSceneName : loseSceneName);
    }
}