欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Unity 2D 学习手札(三) 不同场景间的资料存取

程序员文章站 2022-03-05 14:24:06
单一场景( Scene )的数据的存取,在相对应的脚本( Script )中定义成员变量即可,但仅限于此场景中,并不能将这些变量传递到另一个场景。为了解决不同场景之间数据的传递,以下提供两种解决的方法:一、使用 PlayerPrefs 类PlayerPrefs 类是 Unity 3D 提供的一个用于本地持久保存与读取的类。以键值对的形式将数据保存在文件中,然后程序可以根据这个名称取出所保存的......

单一场景( Scene )的数据的存取,在相对应的脚本( Script )中定义成员变量即可,但仅限于此场景中,并不能将这些变量传递到另一个场景。

为了解决不同场景之间数据的传递,以下提供两种解决的方法:

一、使用 PlayerPrefs 类

PlayerPrefs 类是 Unity 3D 提供的一个用于本地持久保存与读取的类。以键值对的形式将数据保存在文件中,然后程序可以根据这个名称取出所保存的数值。

PlayerPrefs 类只支持三种数据类型:浮点数、整数及字符串。

保存的代码:

PlayerPrefs.SetString("Name", myName);
PlayerPrefs.SetInt("Level", myLevel);
PlayerPrefs.SetFloat("Score", myScore);

读取的代码:

myName = PlayerPrefs.GetString("Name", “default”);
myLevel = PlayerPrefs.GetInt("Level", 0);
myScore = PlayerPrefs.GetFloat("Score", 0.0f);

除了 SetXXX, GetXXX 之外,还提供 HasKey, DeleteKey, DeleteAll, Save等方法。

由于 PlayerPrefs 类是本地永久的储存装置,所以在不同的场景之间可作为数据的传递之用。

二、利用单例设计模式的全局对象

基本工作流程如下图:
Unity 2D 学习手札(三) 不同场景间的资料存取
在场景转换之前,先将数据保存,然后在转换后,立刻读取数据。

首先,在第一个场景中建立一个新的空游戏对象( GameObject ),并将它取一个适合的名称,如:GlobalMaster 或 GlobalObject。

接下来,创建一个新的 C# 脚本,并给它一个名称,例如:GlobalControl。然后将此脚本附加到新的游戏对象。

将此代码放入 GlobalControl 脚本中:

public class GlobalControl : MonoBehaviour {
    public static GlobalControl Instance;
    void Awake() {
        if (Instance == null) {
            DontDestroyOnLoad(gameObject);
            Instance = this;
        } else if (Instance != this) {
            Destroy(gameObject);
        } 
    }
}

这是一个单例设计模式的写法。在此可以添加要保存的变量 HP, Ammo, XP等。

public class GlobalControl : MonoBehaviour {
    public static GlobalControl Instance;
    public float HP;
    public int Ammo;
    public float XP;
    
    void Awake() {
        //.....
    }
}

相关代码如下:

public class PlayerState : MonoBehaviour {
    public float HP;
    public int Ammo;
    public float XP;
    
    void Start () {
        HP = GlobalControl.Instance.HP;
        Ammo = GlobalControl.Instance.Ammo;
        XP = GlobalControl.Instance.XP;
    }
    public void SavePlayer() {
        GlobalControl.Instance.HP = HP;
        GlobalControl.Instance.Ammo = Ammo;
        GlobalControl.Instance.XP = XP;
    }
}

在此范例中,只有三个变量要传递,所以用这种方式并不困难,但如果变量很多时,就不能用这种方式了。

首先,创建一个新的脚本,但不继承 MonoBehavior 类,也不附加到任何对象。通常称之为〝Serializables〞,它看起来像这样:

public class PlayerStatistics {
    public float HP;
    public int Ammo;
    public float XP;
}

正如您所看到的,没有函数、没有名称空间,只有一个没有构造函数的类,及三个已知的变量。

接下来,把 GlobalControl 中的相对应三个变量删除,改成这样子:

public class GlobalControl : MonoBehaviour {
    public PlayerStatistics savedPlayerData = new PlayerStatistics();
    // .....
}

然后 PlayerState 也相对的修改:

public class PlayerState : MonoBehaviour {
    public PlayerStatistics localPlayerData;
    
    void Start() {
        localPlayerData = GlobalControl.Instance.savedPlayerData;
    }
    public void SavePlayer() {
        GlobalControl.Instance.savedPlayerData = localPlayerData;
    }
}

至此,我们将所有与玩家相关的资料都保存在代表玩家数据的类中,增删变量只要修改此类即可,操作上就更简便了。

参考数据:
Saving Data Between Scenes in Unity
By Zdravko Jakupec

本文地址:https://blog.csdn.net/jasper_ding/article/details/85938298

相关标签: Unity 2D Unity