当前位置: 移动技术网 > IT编程>开发语言>JavaScript > Unity 2D 学习手札(三) 不同场景间的资料存取

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

2020年07月28日  | 移动技术网IT编程  | 我要评论
单一场景( 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 类是本地永久的储存装置,所以在不同的场景之间可作为数据的传递之用。

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

基本工作流程如下图:

在场景转换之前,先将数据保存,然后在转换后,立刻读取数据。

首先,在第一个场景中建立一个新的空游戏对象( 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

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网