📜  在统一场景之间切换 - C# (1)

📅  最后修改于: 2023-12-03 15:08:05.841000             🧑  作者: Mango

在统一场景之间切换 - C#

在开发复杂的应用程序时,可能需要引入多个场景(scenes)来组合实现更复杂的交互体验。然而,如何在这些场景之间切换并保持应用程序的运行状态,是一个重要的挑战。

1. 场景管理器

Unity的场景管理器(SceneManager)可以帮助我们实现场景之间的切换和管理。我们可以通过使用SceneManager.LoadScene()方法加载一个场景,并且可以选择在加载时是否保留之前的场景。

SceneManager.LoadScene("MainScene");

如果我们需要在加载场景时传递参数,可以使用SceneManager.LoadScene()方法的另一种重载:

SceneManager.LoadScene("MainScene", LoadSceneMode.Single);

以上代码将通过参数LoadSceneMode.Single表示仅加载新场景并卸载旧场景。

2. 场景之间传递数据

在场景之间切换时,可能需要将一些数据从之前的场景传递给当前场景。一种通用的方法是将数据存储在持久化对象中,比如GameManager单例对象。

public class GameManager : MonoBehaviour
{
    private static GameManager instance;

    private int score;

    // 实现单例模式
    public static GameManager Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new GameObject("GameManager").AddComponent<GameManager>();
            }
            return instance;
        }
    }

    // 获得分数
    public int Score
    {
        get
        {
            return score;
        }
        set
        {
            score = value;
        }
    }

    void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else if (instance != this)
        {
            Destroy(gameObject);
        }
        DontDestroyOnLoad(gameObject);
    }

}

在场景之间传递数据时,只需要在之前场景中修改GameManager的属性或方法,然后在当前场景中读取该属性或调用该方法即可:

GameManager.Instance.Score += 10;
3. 场景之间的通讯

Unity提供了一种简单的方法来在场景之间交换信息:使用事件(Event)。事件允许不同的对象在不同的时间点上发送和接收信息。

为了使用事件,我们先要定义一个委托(Delegate),该委托定义了事件的签名:

public delegate void MyEventHandler(string data);

定义完成后,我们就可以定义事件:

public static event MyEventHandler MyEvent;

事件的触发(Triggering)通常由事件的发布者(Publisher)完成。当事件发生时,它会调用所有已注册的事件处理程序(Handler)。在Unity中,我们可以使用SendMessage()方法或BroadcastMessage()方法来触发事件。

以下是一个使用事件在场景之间进行通讯的例子:

public class Sender : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKey(KeyCode.Space))
        {
            if (MyEvent != null) // 准备触发事件
            {
                MyEvent("Hello, World!"); // 传递数据
            }
        }
    }
}

public class Receiver : MonoBehaviour
{
    void OnEnable()
    {
        MyEvent += PrintMessage; // 注册事件处理程序
    }

    void OnDisable()
    {
        MyEvent -= PrintMessage; // 移除事件处理程序
    }

    void PrintMessage(string data)
    {
        Debug.Log(data);
    }
}
4. 小结

通过场景管理器,我们可以轻松地实现场景之间的切换和管理。通过我的GameManager对象,我们可以在场景之间传递数据。对于更好的交互,我们可以通过事件来实现场景之间的通讯。