前提:导入JSON.NET for Unity插件,资源商店的免费插件
1. 明确需要存储的信息有哪些,我个人习惯是用ScriptableObject作为数据集。
比如我这里有一个简单的背包,背包需要被收集物品的名称、描述,以及在背包UI中显示的图片。
加上CreateAssetMenu属性后可以在资源窗口随意创建,比较舒服。
using UnityEngine;
[CreateAssetMenu(fileName = "New Item", menuName = "Item")]
public class CollectableInfo : ScriptableObject
{
public string itemName;
public string description;
public Sprite artwork;
}
2. 给可收集物品挂上一个脚本,拖入任意一个你需要的ScriptableObject。
下面注释了一大段是因为写不写都可以,只是调用的时候多一个词少一个词的区别。
using UnityEngine;
public class Collectable : MonoBehaviour
{
public CollectableInfo collectableInfo;
//[HideInInspector]
//public string itemName;
//[HideInInspector]
//public string description;
//[HideInInspector]
//public Sprite artwork;
//private void Start()
//{
// itemName = collectableInfo.itemName;
// description = collectableInfo.description;
// artwork = collectableInfo.artwork;
//}
}
3. 将可收集物品拖为预制体,养成好习惯。
4. 明确哪些信息是需要被序列化存储的。
比如在我这个背包系统中,我必须要记录的只有物品的名称和数量,物品的详细信息可以根据物品的名称来动态查询。
public class ItemData
{
public ItemData(string itemName, int itemNum)
{
ItemName = itemName;
ItemNum = itemNum;
}
public string ItemName { get; set; }
public int ItemNum { get; set; }
}
5. 在游戏开始时,先将json文件反序列化为一个列表;在收集物品时,查询列表是否有相同名称,如果有,物品数量+1,如果没有,在列表中新增一个物品信息,然后将列表序列化存储为json文件。
// 核心代码
private string bag_json;
private List<ItemData> bag_list = new List<ItemData>();
private void Start()
{
bag_list.Clear();
bag_json = File.ReadAllText(Application.dataPath + "/bag.json");
bag_list = JsonConvert.DeserializeObject<List<ItemData>>(bag_json);
}
private void CollectFunction()
{
string collectName = hit.collider.GetComponent<Collectable>().collectableInfo.itemName;
bool isCollected = false;
for(int i = 0; i < bag_list.Count; i++)
if (bag_list[i].ItemName == collectName)
{
isCollected = true;
bag_list[i].ItemNum++;
}
if (!isCollected)
bag_list.Add(new ItemData(collectName, 1));
bag_json = JsonConvert.SerializeObject(bag_list, Formatting.Indented);
File.WriteAllText(Application.dataPath + "/bag.json", bag_json);
}
}