如何跨场景保存一些变量的数据? [复制]

Posted

技术标签:

【中文标题】如何跨场景保存一些变量的数据? [复制]【英文标题】:How can i save the data of some variables across scenes? [duplicate] 【发布时间】:2019-08-24 21:44:41 【问题描述】:

我正在制作一款涉及玩家得分的游戏。这个分数总是显示在屏幕上。但是,当我更改场景时,分数会重置回 0。如何才能使分数保存在我的所有场景中?

我已经在互联网上查看了几个小时,但我无法以这种方式修复它。我遇到的两个主要问题是:

    静态变量

    DontDestroyOnLoad()

虽然我确信这些可以解决我的问题,但我不知道如何在我的代码中实现它们。我做一个新脚本吗?我是否将它们放在现有脚本中?如果是这样,是哪一个?如果变量是静态的,如何调用它们?

提前感谢您的帮助!

【问题讨论】:

【参考方案1】:

如果您只是想跨屏幕访问简单数据,静态变量似乎是最直接的解决方案。如果您以前从未使用过它们也没关系,一旦您习惯了它们就会非常容易使用。 :)

首先要做的是创建一个类来保存您的静态变量(是的,这意味着编写一个新脚本并将其放入您的 Scripts 文件夹中)。可以在您已经使用的类上添加新的静态变量,但如果您只是在学习,我建议您将此类内容分开,以便更有条理。

public class GameValues 

    public static int score  get; set; 

    // You can add other static variables here.


请注意,我没有从 MonoBehaviour 继承。这很好,因为我们不需要将此脚本添加到 GameObject,它只是用于存储我们的数据。现在,如果我们需要更改或读取乐谱,我们可以这样做。

public class Example : MonoBehaviour 

    public int scoreLimit = 100;

    private void Update () 

        /* 
         * When accessing static members of a class, no object reference is needed.
         * Instead you access it as though it were a member of the class.
         */
        int currentScore = GameValues.score;

        if (Input.GetKeyDown (KeyCode.Space) && (currentScore < scoreLimit)) 

            GameValues.score += 1;

        
    

显然这是一个相当愚蠢的例子,但你明白了。如果您想进一步阅读,here 是关于 static 关键字的官方 Microsoft 文档。

编码愉快!

【讨论】:

非常感谢,这就是我要找的。像我一样与我交谈的人是一个几乎什么都不懂的初学者,情况确实如此! :P 再次感谢!【参考方案2】:

你有几个选择。

1) PlayerPrefs

Unity 有一个名为 PlayerPrefs 的内置保存程序,它将在场景和游戏重新启动之间存储数据。

//Store Score Value
PlayerPrefs.SetInt("Score", Score);

// Retrieve Score Value if there is one
if (PlayerPrefs.HasKey("Score"))

    Score = PlayerPrefs.GetInt("Score");

PlayerPrefs Documentation

2) Unity 单例

Unity Singleton 与普通编程语言略有不同之处在于它使用DontDestroyOnLoad 来保持GameObject 在场景之间保持Singleton 的活力。

public class UnitySingleton : MonoBehaviour

    public static UnitySingleton Instance  get; private set; 

    public int Score  get; set; 

    private void Awake()
    
        if (Instance != null && Instance != this)
        
            Destroy(gameObject);
        
        else
        
            Instance = this;
            DontDestroyOnLoad(gameObject);
        
    

用法

//Store Score
UnitySingleton.Instance.Score = value;
//Retrieve Score if set otherwise (it will) return 0
Score = UnitySingleton.Instance.Score;

【讨论】:

我们不能用这个来存储数组吗? @SakunaMadushanka 数组是什么? 保存和使用场景之间的数据数组,例如最高评分[100,89,...] 是的,您可以使用 Singleton 方法来保持场景之间的值,但对于在应用程序会话之间存储它们,我建议查看 these 方法以了解如何保存持久数据。 这会有所帮助。提前感谢您的支持。【参考方案3】:

好吧,这是一个最小的例子

保存数据对象:

using UnityEngine;

public class SaveDataHere : MonoBehaviour 

    public string myData;

    public static string staticData = "Static data is still here";

    // Use this for initialization
    void Start () 
        DontDestroyOnLoad(this);

        myData = "I didn't get destroyed haha";

    

在新场景中:

using UnityEngine;
public class InNewScene : MonoBehaviour 

    // Use this for initialization
    void Start () 
        var saveData = FindObjectOfType<SaveDataHere>();
        Debug.Log("instance data is " + saveData.myData);
        Debug.Log("static data is " + SaveDataHere.staticData);
    

【讨论】:

谢谢!我应该在 DontDestroyOnLoad 中放置什么而不是“this”? 您想在场景之间保留的任何对象。如果您将 DontDestroyOnLoad() 放在包含跨场景数据的对象上,则可以将其保留为 this 好吧,酷!在第二个脚本中,我是否需要在此处输入任何内容:“FindObjectOfType();”?或者干脆留空 嗯,你需要一些方法来找到保存数据的对象。由于您是从另一个场景加载对象,因此无法从检查器将两者链接在一起。

以上是关于如何跨场景保存一些变量的数据? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

金融应用场景下跨数据中心的MGR架构方案

如何在跨浏览器中读取剪贴板数据?

Unity3D日常开发Unity3D中使用数据类保存数据,持久保存数据数据存放在跨场景调用数据类

Unity3D日常开发Unity3D中使用数据类保存数据,持久保存数据数据存放在跨场景调用数据类

如何使用 dplyr 将跨因子级别的分组计数保存到新变量中?

Django - 如何将 javascript 变量保存到 Django 数据库中? [复制]