基于 项目02《游戏-05-开发》Unity3D ,
接下来做 背包系统的 存储框架 ,
首先了解静态数据 与 动态数据,静态代表不变的数据,比如下图武器Icon,

其中,武器的名称,描述,图标,星级,详细技能描述都是不变的,称为静态数据,
而动态数据 会随着游戏进度的改变而发生改变,
其中,武器的等级,数量,是否拥有武器等这些都是可变的,成为动态数据,
对于静态数据的配置,有两种比较常用的方案,
第一种是使用Excel表格进行配置,
第二种是使用unity内置的【Scripper object】进行配置,
其中使用Ecel表格的可视化会更强大,适用于多人协作,缺点是步骤比较繁琐,需要多一步导出操作,
因此我们使用【Scripper object】进行配置,
对于动态数据的配置,也有两种方法,
第一种是存储在服务器上,登陆的时候从服务器拉取数据,
第二种是存储在本地,登陆的时候从文本文件中去读取当前的进度,

这两种最大的区别是一个记录在远程的机器上,一个记录在本地的机器上,
也就是网游和单机的区别,
本次我们使用第二种方案【JSON】
首先我们进行静态数据的配置,
创建背包表格PackageTable.cs脚本,功能是使用右键在unity编辑器中创建一个自定义配置文件,
可以传入两个参数,一个是菜单名称,另一个是创建后文件的名称,

双击PackageTable.cs修改脚本:

using System.Collections.Generic;
 using UnityEngine;
 [CreateAssetMenu(menuName = "Water/PackageTable",fileName = "PackageTable")]
 public class PackageTable : ScriptableObject{
     public List<PackageTableItem> dataList = new List<PackageTableItem>();
 }
 [System.Serializable]
 public class PackageTableItem {
     public int id;
     public int type;
     public int star;
     public string name; 
     public string description;
     public string skillDescription;
     public string imagePath;
 }
 【解释】

其中使用List列表来容纳所有物品,

回到unity编辑器中,右键创建一个自己的文件用来容纳表格中的静态数据,

此时就创建了一个静态数据项,

在检查窗口Inspector中,可以看到一个List列表用来添加子项,


以此类推做八个,




回到unity编辑器创建修改器脚本GMCmd.cs

双击修改器脚本GMCmd.cs修改代码:

using UnityEditor;
 using UnityEngine;
 public class GMCmd{
     [MenuItem("CMCmd/读取表格")]
     public static void ReadTable(){
         PackageTable packageTable = Resources.Load<PackageTable>("TableData/PackageTable");
         foreach (PackageTableItem packageItem in packageTable.dataList)
             Debug.Log(string.Format($"[id] {packageItem.id} [name] {packageItem.name}"));
     }
 }
 回到unity编辑器中将TableData文件夹放在Resources文件夹下,

在unity菜单栏中可以看到创建的修改器,

点击读取表格可以看到读取数据,

配置好静态数据之后,接下来配置动态数据:
首先创建脚本PackageLocalData.cs
这个脚本的功能是将背包数据以Json的格式存储在本地,并且在使用时将其从本地的文本文件中读取到内存中,为方便使用,将代码设置为单例模式,类似于静态数据,动态数据也有背包物品的每一个子项,将这个子项命名为PackageLocalItem,它包含唯一的一个标识符uid,用来表示它是哪个物体的ID这个物品的数量num,以及物品等级level,是不是新获得的物品isNew,最后重写这个子类的ToString方法,方便后面打印和调试,最后添加List完善这个存取框架,用list容器缓存当前所有物品的动态信息,然后两个方法,存和取,而去文件的方法核心思想就是把文件变成字符串,再把字符串变成类的一个操作,

双击脚本PackageLocalData.cs修改代码:

using System.Collections.Generic;
 using UnityEngine;
 public class PackageLocalData{
     static PackageLocalData _instance;
     public static PackageLocalData Instance{
         get{
             if (_instance == null)
                 _instance = new PackageLocalData();
             return _instance;
         }
     }
     //存
     public List<PackageLocalItem> items;
     public void SavaPackage(){
         string inventoryJson = JsonUtility.ToJson(this);
         PlayerPrefs.SetString("PackageLocalData", inventoryJson);
         PlayerPrefs.Save();
     }
     //取
     public List<PackageLocalItem> LoadPackage(){
         if (items != null)
             return items;
         if (PlayerPrefs.HasKey("PackageLocalData")){
             string inventoryJson = PlayerPrefs.GetString("PackageLocalData");
             PackageLocalData packageLocalData = JsonUtility.FromJson<PackageLocalData>(inventoryJson);
             items = packageLocalData.items;
             return items;
         }
         else{
             items = new List<PackageLocalItem>();
             return items;
         }
     }
 }
 [System.Serializable]
 public class PackageLocalItem{
     public string uid;
     public int id;
     public int num;
     public int level;
     public bool isNew;
     public override string ToString(){
         return string.Format($"[id] {id} [num] {num}");
     }
 }
 然后修改修改器GMCmd.cs脚本 : 在修改器脚本中调用动态数据的功能,

using System;
 using System.Collections.Generic;
 using UnityEditor;
 using UnityEngine;
 public class GMCmd{
     [MenuItem("CMCmd/读取表格")]
     public static void ReadTable(){
         PackageTable packageTable = Resources.Load<PackageTable>("TableData/PackageTable");
         foreach (PackageTableItem packageItem in packageTable.dataList)
             Debug.Log(string.Format($"[id] {packageItem.id} [name] {packageItem.name}"));
     }
     [MenuItem("CMCmd/创建背包测试数据")]
     public static void CreateLocalPackageData(){
         //保存数据
         PackageLocalData.Instance.items = new List<PackageLocalItem>();
         for (int i = 1; i < 9; i++){
             PackageLocalItem packageLocalItem = new(){
                 uid = Guid.NewGuid().ToString(),
                 id = i,
                 num = i,
                 level = i,
                 isNew = i % 2 == i
             };
             PackageLocalData.Instance.items.Add(packageLocalItem);
         }
         PackageLocalData.Instance.SavaPackage();
     }
     [MenuItem("CMCmd/读取背包测试数据")]
     public static void ReadLocalPackageData(){
         //读取数据
         List<PackageLocalItem> readItems = PackageLocalData.Instance.LoadPackage();
         foreach (PackageLocalItem item in readItems)
             Debug.Log(item);
     }
 }
 回到unity编辑器中使用动态数据功能,运行游戏先创建背包测试数据,

再点击读取背包测试数据,

可以看到调用背包动态数据成功,
End.