统一加载另一个场景时

时间:2019-08-20 16:51:12

标签: c# unity3d

我创建了一个足球比分计算器。我有一个可以更改场景的按钮,但是当我更改场景并重新打开它时,得分值将重置为0。这是代码:

public class Main : MonoBehaviour {
    public Text plusUp;
    public int value = 0;

    public void button(int sc)
    {
        SceneManager.LoadScene(sc);
    }

    public void plus()
    {
        value++;
        plusUp.text = value.ToString();
    }
}

2 个答案:

答案 0 :(得分:4)

1。。您可以在包含要保存的变量的对象上使用方法Object.DontDestroyOnLoad。加载另一个场景时,它将使GameObject这个脚本的附加内容仍然有效:

void Awake()
{
    DontDestroyOnLoad(this.gameObject);
}

有关更多信息,请参见documentation

您也可以制作一个Singleton,但是这种设计模式稍微复杂一点,因为在加载另一个场景时Unity会破坏它。您仍然必须使用DontDestroyOnLoad来了解如何在他们的GitHub page上实现此模式


2。。或者,您可以在加载另一个场景之前将值保存在磁盘上,然后使用PlayerPrefs帮助方法加载该值:

public int value = 0;

void Awake()
{
    //Load the saved score (this value will be saved even if you restart the app)
    value = PlayerPrefs.GetInt("Score");
}

public void button1(int sc)
{
    //Save your value before you load the scene
    PlayerPrefs.SetInt("Score", value);
    SceneManager.LoadScene(sc);
}    

有关类型的更多信息,请参见documentation

答案 1 :(得分:4)

有一些核心概念对理解这个问题很有用。

  1. 作用域:每个场景都在其自己的作用域中运行。一个场景中发生的任何变量,对象或更改都不会自动转移到另一场景。启动场景时,场景中的所有对象都被实例化和初始化,并且如果它们是Monobehaviours,则调用它们的Awake()/ Start()方法。

  2. 初始化-实例化对象时,将使用构造函数或默认值对其进行初始化。 Monobehaviours没有构造函数,因此任何变量都将推迟回默认值。

  3. 数据持久性-更改场景时,先前场景中的所有游戏对象都将被销毁,而新场景中的所有对象都将被实例化和初始化。由于先前场景中的所有对象都被破坏,因此在这些对象上设置的所有值都将消失。您可以使用DoNotDestroyOnLoad()防止销毁GameObject,但这不会覆盖新场景中定义的对象。通常不建议将DoNotDestroyOnLoad()用作游戏逻辑的核心部分,因为它通常会导致场景相互依赖(场景1必须定义GameObject的值并将其传递给场景2,可用” =不良做法)。

解决您的问题

您似乎想不考虑场景而将分数保留为一个值。由于所有GameObjects和Monobehaviours都位于场景中,因此您可以:

  1. 使用Singleton pattern强制将对象逼近场景。

  2. 每当得分数据变化时将分数数据存储到文件中,并通过Start()方法从该文件中读取。

  3. 我推荐的方法:使用ScriptableObject来保存分数,并在更改分数和更新游戏对象时刷新该对象。 ScriptableObjects在项目级别作用域,因此它们会在场景之间自动保留。