【问题标题】:Save Game Using JSON in Unity [duplicate]在 Unity 中使用 JSON 保存游戏 [重复]
【发布时间】:2017-04-11 12:08:28
【问题描述】:

我使用 Unity 的 JSON 序列化在 Unity 中创建了一个简单的保存游戏系统。我的保存游戏非常简单,我只是保存角色的位置并加载它。

保存游戏运行良好,在游戏中。当我启动游戏并单击“保存”时,游戏会被保存,并且 JSON 文件会根据我的玩家位置进行更新。当我点击“加载”时,游戏加载正常,我的玩家被移动到之前保存的位置。

但是我的问题是,每当我关闭游戏并重新启动它时,“加载”功能只会将我的角色重置到我生成它的位置。它不会加载我在上一场比赛中之前保存的位置的角色。

现在是我的代码。我有一个包含我的演员数据的演员类:

using UnityEngine;
using System.Collections;
using System;

public class Actor : MonoBehaviour
{

    public ActorData data = new ActorData(); // to store our data

    public void StoreData() // for storing our data
    {
        data.pos = transform.position;
    }

    public void LoadData() // for loadinjg our data
    {
        transform.position = data.pos;
    }

    public void ApplyData()
    {
        SaveData.AddActorData(data);
    }

    void OnEnable() // to enable the save/load to avoid hanging
    {
        SaveData.OnLoaded += LoadData;
        SaveData.OnBeforeSave += StoreData;
        SaveData.OnBeforeSave += ApplyData;
    }

    void OnDisable() // to disable the save/load to avoid hanging
    {
        SaveData.OnLoaded -= LoadData;
        SaveData.OnBeforeSave -= StoreData;
        SaveData.OnBeforeSave -= ApplyData;
    }
}

[Serializable] // for storing in JSON
public class ActorData // our players attributes in JSON
{
    public Vector3 pos;
}

我还有一个 ActorContainer 来保存不同玩家的数据:

using System.Collections.Generic;
using System;

[Serializable]
public class ActorContainer
{

    // To store our different actors data
    public List<ActorData> actors = new List<ActorData>();
}

我有一个 SaveData 类来执行我的序列化:

    using UnityEngine;
using System.Collections;
using System.IO;

public class SaveData
{

    // every actos will be sorted in this actor container when loading the game
    public static ActorContainer actorContainer = new ActorContainer(); // static so that we dont have to recreacte savedata everytime

    public delegate void SerializeAction();
    public static event SerializeAction OnLoaded; // happens after loading
    public static event SerializeAction OnBeforeSave; // right before saving

    public static void Load(string path) // where the load is
    {
        actorContainer = LoadActors(path);

        OnLoaded();

        ClearActorList(); // so that there's no duplicates
    }

    public static void Save(string path, ActorContainer actors)
    {
        OnBeforeSave(); // to throw of the data that was in OnBeforeSave

        SaveActors(path, actors); // store all of our actors as json in the file

        ClearActorList(); // clear the list so that the next time we save theres no duplicates
    }

    public static void AddActorData(ActorData data)
    {
        actorContainer.actors.Add(data);
    }

    public static void ClearActorList() // to avoid duplicate data
    {
        actorContainer.actors.Clear(); // access actors and clear it
    }

    private static ActorContainer LoadActors(string path) // path to the JSON
    {
        string json = File.ReadAllText(path); // loading all the text out of the file into a string, assuming the text is all JSON

        return JsonUtility.FromJson<ActorContainer>(json); // parse the JSON into an ActorContainer type and return in the LoadActors
    }

    private static void SaveActors(string path, ActorContainer actors) // where to save and the actors to save
    {
        string json = JsonUtility.ToJson(actors);

        StreamWriter sw = File.CreateText(path); // if file doesnt exist, make the file in the specified path
        sw.Close();

        File.WriteAllText(path, json); // fill the file with the data(json)
    }
}

最后我有一个 GameController 类,它充当 Unity 的通信器:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.IO;

public class GameController : MonoBehaviour
{ // to tell unity what it has to do, a communicator to be used with unity

    // trigger buttons
    public Button saveButton;
    public Button loadButton;

    private static string dataPath = string.Empty;

    void Awake()
    {
        dataPath = System.IO.Path.Combine(Application.persistentDataPath, "actors.json"); // persistentDataPath unity save game path, actors.json name of the file containing actors 
    }

    // for button
    public void Save()
    {
        SaveData.Save(dataPath, SaveData.actorContainer);
    }

    // for button 
    public void Load()
    {
        SaveData.Load(dataPath);
    }
}

我的 JSON 文件 actor.json 包含以下内容:

{"演员":[{"pos":{"x":419.6240539550781,"y":5.0189208984375,"z":0.0}}]}

欢迎提出任何建议。

【问题讨论】:

  • 你永远不会在Actor.cs中将加载的值分配给data.pos

标签: c# json unity3d


【解决方案1】:

所以问题很简单,您永远不会将 JSON 中加载的值分配给 Actor.cs 中的 data.pos。相反,您从公共字段 ActorData data 加载它,该字段没有更改。

如果我能看到这个权利,你必须在Actor.cs 中更改以下内容:

using System.Linq;

// ..

public void LoadData() 
{
    // guessing you will implementing an identifier for the separate actors later..
    var currentActor = SaveData.actorContainer.First();
    transform.position = currentActor.pos;

    // also set the loaded data to the field
    data = currentActor;
}

// ..

【讨论】:

  • 你说的完全正确!谢谢你:)
  • @arjwolf 很高兴我能帮上忙! :D
猜你喜欢
  • 2018-04-11
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多