Unity3d中使用ScriptableObject实现简单的本地排行榜功能
发表于2018-07-26
最近有个项目中需要实现一个排行榜系统,只需显示排名和分数,一开始想用sqlite做一个简单的数据库,但是在写文件的时候发现,由于sqlite只支持单线程的写操作,所以在更新排行榜的时候会出现数据库lock的现象。由于排行榜十分简单,所以想着不如用ScriptableObject来实现。当然设计一下感觉ScriptableObject也是可以用来实现数据库的功能的。
ScriptableObject是一个可继承且不需要挂载在游戏物体上的类,我们可以使用继承了ScriptableObject的类来存储程序数据,例如配置,游戏中的角色信息等等,也可以存储一些预置方案来供程序选择。ScriptableObject会对数据进行序列化存储,如果我们需要设计一些比较复杂的类来存储信息,我们可以加上[Serializable]标记来对类指定的类进行序列化,同时也可以使用[NonSerialized]对特定的变量取消序列化,加了次标记的变量也不会出现在编辑面板上。有些类型如Dictionary是不能序列化的。
[Serializable] public class DataBase { public string key; public string[] values; [NonSerialized] public int index; }
首先新建一个Class,继承ScriptableObject,这个类有一个int类型的数组变量scores用来存储排行榜中的分钟。项目需要显示前20名,所以我申请了一个长度为20的数组变量。代码如下:
public class HMDataBase : ScriptableObject { public int[] scores = new int[20]; }
然后重写HMDataBase类的Editor,代码如下:
[CustomEditor(typeof(HMDataBase))] public class HMDataBaseEditor : Editor { public override void OnInspectorGUI() { base.OnInspectorGUI(); } } public class HMDataBaseAsset { [MenuItem("Assets/Create/HM DataBase", false, 0)] public static void CreateAsset() { HMDataBase asset = ScriptableObject.CreateInstance<HMDataBase>(); string path = AssetDatabase.GetAssetPath(Selection.activeObject); string fileName = "New HM DataBase"; string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(path + "/" + fileName + ".asset"); AssetDatabase.CreateAsset(asset, assetPathAndName); AssetDatabase.SaveAssets(); EditorUtility.FocusProjectWindow(); Selection.activeObject = asset; } }
这样我们右键Project视图的Assets目录下的地方就能新建HMDataBase类型的asset文件,这个文件会被序列化,可以用来改修和存储项目中的排行榜信息:
然后我们在程序中定义一个HMDataBase的变量,就能对chart中的scores进行读写操作了。
public HMDataBase chart; public int ReadChartByID(int id) { if(id < 0 || id > 20) { Debug.Log(id out of range); return -1; } return chart.scores[id]; } public void UpdateChart(int id, int score) { if(id < 0 || id > 20) { Debug.Log(id out of range); return; } chart.scores[id] = socre; }
我们可以为HMDataBase添加更多的方法以便进行数据的操作。
其实ScriptableObject可以实现的功能远不止这么简单,有时间我会设计一个复杂一点的类数据库系统,也方便以后程序的编写。之后会继续分享关于ScriptableObject的一些使用心得。