Unity3d中使用ScriptableObject实现简单的本地排行榜功能

发表于2018-07-26
评论0 2.8k浏览
最近有个项目中需要实现一个排行榜系统,只需显示排名和分数,一开始想用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的一些使用心得。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引