保存/加载Unity3d

4
我正在尝试每当玩家到达传送门时保存游戏,然后当游戏停止并且玩家想再次玩时,他可以在开始菜单上按继续按钮以从他上次解锁的级别开始。
以下是教程链接: http://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/persistence-data-saving-loading 以下是应该保存游戏的传送门脚本之一:
    using UnityEngine;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public class Saving : MonoBehaviour
{

    void OnTriggerEnter( Collider other)
    {
        if(other.gameObject.tag == "Player")
        {
            GameControl.control.levelcount += 1;
            GameControl.control.Save();
        }
    }
}

没有出现错误。

这是继续按钮的脚本:

using UnityEngine;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public class ContinueCS : MonoBehaviour {

    void OnMouseUp(){
        GameControl.control.Load();
        int levelcount =  GameControl.control.levelcount;
        if(levelcount == 0)
        {
            Application.LoadLevel("Level1");
        }
        else
        Application.LoadLevel(levelcount);
    }
}

没有错误

以下是基于教程的脚本:

    using UnityEngine;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

     public class GameControl : MonoBehaviour {
    public static GameControl control;

    public float score;
    public int levelcount;

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

    public void Save()
    {
        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Create(Application.persistentDataPath + "/playerInfo.dat");

        PlayerData data = new PlayerData();
        data.score = score;
        data.levelcount = levelcount;

        bf.Serialize(file, data);
        file.Close();
    }
    public void Load()
    {
        if(File.Exists(Application.persistentDataPath + "/playerInfo.dat"))
        {
            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Open(Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
            PlayerData data = (PlayerData)bf.Deserialize(file);
            file.Close();

            score = data.score;
            levelcount = data.levelcount;

        }
    }
}
[Serializable]
class PlayerData
{
    public float score;
    public int levelcount;
}

编辑:这是当前的脚本,仍然无法加载最后一个解锁的关卡,它会一直加载第一关,如果我从continuescript中删除if语句,只留下这个:

void OnMouseUp(){
        GameControl.control.Load();
        int levelcount =  GameControl.control.levelcount;
        Application.LoadLevel(levelcount);


it simply does nothing so i'm guessing the levelcount just isn't adding up.

我开始使用GameControl.control.x,因为在教程中这个方法可以用来加载、保存或添加变量。唯一的区别是所有的操作都需要通过GUI按钮实现。由于control是静态的,所以GameControl.control.levelcount +=1;应该可以正常工作,对吗?

不要再使用 BinaryFormatter 了!请改用 XML、JSON 或类似的格式。详情请见:二进制序列化程序的安全性指南 - derHugo
1个回答

2
当您加载数据时,您会从文件中反序列化数据,并使用旧变量覆盖新反序列化数据。
if(File.Exists(Application.persistentDataPath + "/playerInfo.dat"))
{
    BinaryFormatter bf = new BinaryFormatter();
    FileStream file = File.Open(Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
    PlayerData data = (PlayerData)bf.Deserialize(file);
    file.Close();

    //These lines overwrites the loaded data
    data.score = score;
    data.levelcount = levelcount;
}

只需更改顺序,将值移动到变量中即可。

if(File.Exists(Application.persistentDataPath + "/playerInfo.dat"))
{
    BinaryFormatter bf = new BinaryFormatter();
    FileStream file = File.Open(Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
    PlayerData data = (PlayerData)bf.Deserialize(file);
    file.Close();

    score = data.score;
    levelcount= data.levelcount;
}

谢谢回复,我的确犯了一个错误。我更改了它并在编辑器和构建游戏(重建后)中尝试了一下,但仍然不起作用,可能是其他问题吗?在继续脚本中:我更改了 Application.LoadLevel("Level1"); 到 Application.LoadLevel("level3") 进行测试,然后它加载第 3 关,如果我删除整个 if 语句,只留下 Application.LoadLevel(levelcount);,按下继续按钮将不起作用,因此我认为 levelcount 由于某种原因未增加。 - Dane Gillis
我看不到任何错误。你确定路径存在 Application.persistentDataPath + "/playerInfo.dat" 吗? 尝试使用 Debug.Log 找出错误发生的位置。 - Imapler
我已经检查过了,它确实存在。我将更新我的帖子中的脚本,因为它们不再正确,因为我正在在savescript中添加+1,并且刚注意到帖子中的脚本甚至都没有这样做。给我一点时间,我也会尝试使用debug.log。 - Dane Gillis
哦,也许路径不对了,这里是我找到playerInfo.dat的地方: C:\Users\Dane\AppData\LocalLow\DefaultCompany\New Unity Project但如果保存函数创建了这个路径并将playerinfo.dat保存在那里,那么加载函数不应该也能在这个位置找到它吗? - Dane Gillis
不要再使用BinaryFormatter了!!请改用XML、JSON或类似的格式。点击此处查看更多信息。 - derHugo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接