• 转载unity编辑器xml数据库插件


    unity编辑器xml数据库插件

    注:9月9日更新,其中MyXML.cs中有一句代码写错,查找功能失误,文中已经修改!

    注:9月1日更新说明:xml存储结构,因为在用xml之前不知道正规的xml数据结构,所以是自创的结构。虽然也能完成功能,但是据说策划配置时不方便,所以为了统一,不使用节点的方式存储数据,

    而是通过添加属性,设置属性的方式来存取数据。

    直接上图看的清楚些:

    我之前设计的格式:

    现在的格式:

    关于这部分的代码我会贴在最后。

    程序和数据分离的意义我就不多说了,大家自己脑补或者百度。在使用unity开发时,数据的调试是非常频繁和重要的。我们可以制作一个简单的编辑器插件,将数据显示在Inspector面板上,并进行编辑操作。这样测试人员就可以非常方便的管理测试数据了。

    需求很简单,具体的效果是,能读取资源内的类,将其属性显示在面板上,可以对此进行增删改查的操作。如下图所示(对象组,相当于数据库所有的表。对象,相当于表的所有记录)。

     

     

    当需要创建一条新记录的时候,先填上主键,然后点击创建按钮。编辑完成后点击插入即可。

     

     

    xml数据库文件如下图

    要实现这个功能,需要的知识是,C#的反射类,unity的编辑器类,数据库。通过反射,自动解析对象,获取对象的成员变量名和值。Unity编辑器类没什么好说的,就是一些组件方法的使用。考虑到跨平台等问题,我选择xml作为存储数据库。编辑器内运行,存储量不大,所以性能方面的问题也就不说了。

    好,接下来说一说设计的事。首先是对象的反射。基本类型的存储没有问题,难点是数组的存取有点变态。我找了很多资料也不能自动创建某一类型的数组。既然不能自动,然后就使用半自动判断了,无非是if else之类的,看看这个属性是不是某一类型的数组。

    下面是代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    using System;
    using System.Reflection;
    using UnityEngine;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    public class ClassAnalyze<T>
    {
        private string[] cols;
     
        public string[] Cols
        {
            get return cols; }
            set { cols = value; }
        }
        private string[] values;
     
        public string[] Values
        {
            get return values; }
            set { values = value; }
        }
     
        public string ClazzName
        {
            get return tempClazz.GetType().Name; }
     
        }
        private PropertyInfo[] property;
        private T tempClazz;
     
        public static System.Object CreateObject(string objName) {
            return Assembly.GetExecutingAssembly().CreateInstance(objName);
        }
        public T GetClazz(string[] values)
        {//将数值赋给对象,然后再获取
     
            SetClazz(values);
            this.Values = values;
            if (tempClazz == null)
            {
                return default(T);
            }
            return tempClazz;
        }
        public void SetClazz(string[] values)
        {//将数值赋给对象,然后再获取
     
            if (tempClazz != null && this.Values.Length == values.Length)
            {
                this.Values = values;
                for (int i = 0; i < property.Length; i++)
                {
                    if (tempClazz.GetType().GetProperty(Cols[i]).PropertyType.IsArray)
                    {
     
                        var tempArr = StringToArr(tempClazz.GetType().GetProperty(Cols
    [i]).GetValue(tempClazz, null), values[i].Split(new char[] { '|' }));
     
                        property[i].SetValue(tempClazz, tempArr, null);
                    }
                    else
                    {
                        property[i].SetValue(tempClazz, Convert.ChangeType(values[i], property[i].PropertyType), null);
                    }
                }
            }
        }
        private System.Object StringToArr(System.Object arr, string[] values)
        {
            if (arr is string[])
            {
                arr = new string[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    (arr as string[])[i] = values[i];
                }
                return (string[])arr;
            }
            else if (arr is int[])
            {
                arr = new int[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    (arr as int[])[i] = int.Parse(values[i]);
                }
                return (int[])arr;
            }
            else if (arr is Single[])
            {
                arr = new Single[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    (arr as Single[])[i] = Single.Parse(values[i]);
                }
                return (Single[])arr;
            }
            else if (arr is float[])
            {
                arr = new float[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    (arr as float[])[i] = float.Parse(values[i]);
                }
                return (float[])arr;
            }
            else if (arr is double[])
            {
                arr = new double[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    (arr as double[])[i] = double.Parse(values[i]);
                }
                return (double[])arr;
            }
            else if (arr is long[])
            {
                arr = new long[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    (arr as long[])[i] = long.Parse(values[i]);
                }
                return (long[])arr;
            }
            else if (arr is System.Object[])
            {
                arr = new System.Object[values.Length];
     
                for (int i = 0; i < values.Length; i++)
                {
     
                    (arr as System.Object[])[i] = values[i];
                }
                return (System.Object[])arr;
            }
     
     
            return arr;
        }
     
        private string ArrToString(System.Object arr)
        {
     
            string values = "";
     
     
            if (arr is System.Object[])
            {
                foreach (var value in arr as System.Object[])
                {
                    values += value + "|";
                }
            }
            else if (arr is string[])
            {
                foreach (var value in arr as string[])
                {
                    values += value + "|";
                }
            }
            else if (arr is int[])
            {
                foreach (var value in arr as int[])
                {
                    values += value + "|";
                }
            }
            else if (arr is Single[])
            {
                foreach (var value in arr as Single[])
                {
                    values += value + "|";
                }
            }
            else if (arr is float[])
            {
                foreach (var value in arr as float[])
                {
                    values += value + "|";
                }
            }
            else if (arr is double[])
            {
                foreach (var value in arr as double[])
                {
                    values += value + "|";
                }
            }
            else if (arr is long[])
            {
                foreach (var value in arr as long[])
                {
                    values += value + "|";
                }
            }
     
            values = values.TrimEnd(new char[] { '|' });
            return values;
        }
        public void AnalyzeClazz()
        {
            if (tempClazz != null)
            {
     
                property = tempClazz.GetType().GetProperties();
                Cols = new string[property.Length];
                Values = new string[property.Length];
                for (int i = 0; i < property.Length; i++)
                {
                    Cols[i] = property[i].Name;
                    string value = "";
                    if (tempClazz.GetType().GetProperty(Cols[i]).PropertyType.IsArray)
                    {
                        value = ArrToString(tempClazz.GetType().GetProperty(Cols[i]).GetValue(tempClazz, null));
                    }
                    else
                    {
                        value = Convert.ToString(tempClazz.GetType().GetProperty(Cols[i]).GetValue(tempClazz, null));
                    }
                    Values[i] = value;
                }
            }
        }
        private ClassAnalyze()
        {
     
        }
        public ClassAnalyze(T tempClazz)
        {
            this.tempClazz = tempClazz;
            AnalyzeClazz();
        }
     
        public void Close()
        {
            tempClazz = default(T);
            Cols = null;
            Values = null;
            property = null;
        }
        public System.Object GetValue(T t, string colName)
        {
            return tempClazz.GetType().GetProperty(colName).GetValue(tempClazz, null);
        }
        public void SetValue(T t, string colName,string value)
        {
            for (int i = 0; i < property.Length; i++) {
                if (property[i].Name == colName) {
                    if (property[i].PropertyType.IsArray)
                    {
                        var tempArr = StringToArr(property[i].GetValue(tempClazz, null), value.Split(new char[] { '|' }));
     
                        property[i].SetValue(tempClazz, tempArr, null);
                    }
                    else {
                        property[i].SetValue(tempClazz, Convert.ChangeType(value, property[i].PropertyType), null);
                     
                    }
                    break;
                }
            }
     
        }
     
        public override string ToString()
        {
            string values = "";
            for (int i = 0; i < Cols.Length; i++)
            {
                values += Cols[i] + ":{" this.Values[i] + "} ";
            }
     
            return base.ToString() + ": " + values;
        }
    }

      

    反射搞定后就是设计xml数据库了,具体的功能看个人需求。关于操作xml还是很简单的。

     

    复制代码
    using System.Xml;
    using System.Collections.Generic;
    using System.IO;
    using System;
    
    using UnityEngine;
    public abstract class DB
    {
        /*public abstract bool CheckTable(string tableName);
        public abstract bool CheckDB(string dBName);
        public abstract void CreateTable(string tableName);
        public abstract void CreateDB(string dBName);*/
        public abstract bool Insert(string tableName, string[] cols, string[] values, string key);
        public abstract bool Update(string tableName, string[] cols, string[] values, string key);
        public abstract bool UpdateAll(string tableName);
        public abstract bool Delete(string tableName,  string key);
        public abstract bool DeleteAll(string tableName);
        public abstract string[] Select(string tableName, string key);
        public abstract List<string[]> SelectAll(string tableName);
        public abstract void Connect(string path);
        public abstract void Close();
        public abstract string[] SelectAllObjectsName(string tableName);
        
    }
    public class XmlSql : DB
    {
        //public static string values[0] = "values[0]";
        private XmlDocument xmlDoc;
        private string path;
        private string rootName;
        public XmlSql()
        {
            xmlDoc = new XmlDocument();
        }
        public XmlSql(string path)
        {
            xmlDoc = new XmlDocument();
            Connect(path);
        }
        public override void Connect(string path)
        {
            if (xmlDoc == null) xmlDoc = new XmlDocument();
            if (!CheckDB(path))
            {
                this.path = path;
                rootName = path.Substring(path.LastIndexOf("/")+1,path.LastIndexOf(".")- path.LastIndexOf("/")-1);
                CreateDB(rootName);
            }
            else {
                this.path = path;
                
                xmlDoc.Load(this.path);
                rootName = xmlDoc.LastChild.LocalName;
            }
        }
        public override void Close()
        {
            if (xmlDoc != null)
            xmlDoc.Save(path);
            GC.Collect();
        }
    
    
        public XmlNode CheckTable(string tableName)
        {
            XmlNode root = xmlDoc.SelectSingleNode(rootName);
            if (root.SelectSingleNode(tableName) != null) {
                return root.SelectSingleNode(tableName);
            }
    
            return CreateTable(root,tableName);
        }
        public bool CheckDB(string dBName)
        {
            return File.Exists(dBName);
        }
        public XmlNode CreateTable(XmlNode root,string tableName)
        {
            XmlNode table = xmlDoc.CreateElement(tableName);
            root.AppendChild(table);
            xmlDoc.Save(path);
            return table;
        }
        public XmlNode CreateDB(string dBName)
        {
            File.CreateText(path).Close();
            XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
            XmlNode root = xmlDoc.CreateElement(dBName);
            xmlDoc.AppendChild(xmlDeclaration);
            xmlDoc.AppendChild(root);
            xmlDoc.Save(path);
            return root;
        }
    
    
        public override bool Insert(string tableName, string[] cols, string[] values,string key)
        {
    
            if (key == null || key == "") key = values[0];
            key = key.Replace(" ","");
            XmlNode table = CheckTable(tableName);
    
            XmlNode obj = table.SelectSingleNode(key);//按照key值确定元素对象
    
            if (obj != null) {//待插入数据已经存在,插入失败
                return false;
            }
    
            XmlElement element = xmlDoc.CreateElement(key);
    
            for(int i=0;i<cols.Length;i++){
                XmlElement e = xmlDoc.CreateElement(cols[i]);
                e.InnerText = values[i].Replace(" ", "");
                element.AppendChild(e);
            }
            table.AppendChild(element);
            xmlDoc.Save(path);
            return true;
        }
        public override bool Update(string tableName, string[] cols, string[] values,string key)
        {
            if (key == null || key == "") key = values[0];
            key = key.Replace(" ", "");
            XmlNode table = CheckTable(tableName);
    
            XmlNode obj = table.SelectSingleNode(key);//按照key值确定元素对象
            if (obj == null)
            {//待更新数据不存在,更新失败
                return false;
            }
            for (int i = 0; i < cols.Length; i++)
            {
                obj.SelectSingleNode(cols[i]).InnerText = values[i].Replace(" ", "");
            }
            xmlDoc.Save(path);
            return true;
    
           
        }
    
        public override bool UpdateAll(string tableName)
        {
            return false;
        }
        public override string[] Select(string tableName, string key)
        {
            XmlNode table = CheckTable(tableName);
            if (key == null || key == "") {
                if (table.ChildNodes.Count < 1) { 
                return null;
                }
                key = table.ChildNodes[0].LocalName;
            } 
            key = key.Replace(" ", "");
            
            XmlNode obj = table.SelectSingleNode(key);//按照key值确定元素对象
    
            if (obj == null) {
                return null;
            }
    
            string[] values = new string[obj.ChildNodes.Count];
    
            for (int i = 0; i < values.Length; i++) {
                values[i] = obj.ChildNodes.Item(i).InnerText.Replace(" ", "");
            }
    
            return values;
        }
        public override string[] SelectAllObjectsName(string tableName)
        {
            XmlNode table = CheckTable(tableName);
            
            string[] values = new string[table.ChildNodes.Count];
    
            for (int i = 0; i < values.Length; i++) {
                values[i] = table.ChildNodes[i].LocalName;
            }
            return values;
        }
        public override List<string[]> SelectAll(string tableName)
        {
            XmlNode table = CheckTable(tableName);
            if (table.ChildNodes.Count == 0) {
                return null;
            }
            List<string[]> elements = new List<string[]>();
            for(int i=0;i<table.ChildNodes.Count;i++){
    
                string[] values = new string[table.ChildNodes[i].ChildNodes.Count];
                for (int j = 0; j < table.ChildNodes[i].ChildNodes.Count; j++) {
    
                    values[j] = table.ChildNodes[i].ChildNodes.Item(j).InnerText.Trim();
                }
                elements.Add(values);
            }
            return elements;
        }
        public override bool Delete(string tableName, string key)
        {
            XmlNode table = CheckTable(tableName);
            if (key == null || key == "") key = table.ChildNodes[0].LocalName;
            key = key.Replace(" ", "");
            
    
            XmlNode obj = table.SelectSingleNode(key);//按照key值确定元素对象
            if (obj == null)
                return false;
            obj.RemoveAll();
            table.RemoveChild(obj);
            xmlDoc.Save(path);
            return true;
        }
        public override bool DeleteAll(string tableName)
        {
            XmlNode table = CheckTable(tableName);
            table.RemoveAll();
            xmlDoc.Save(path);
            return true;
        }
    }
    复制代码

    接下来就是编辑器的设计。没什么高大上的东西,就是一些读写和调用的方法,以及一些逻辑上的处理。

     

    复制代码
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using System.Reflection;
    using System;
    public class MyInspector : MonoBehaviour {
    
        //这个类是一个编辑器类,作用是展示存储的xml数据
        //选择对象,然后进行编辑
        //如果数据库中有这个数值,将其读取并显示
        //如果没有,则按需求创建数据
        //public string path;
    
        public string defaultKey = "PriKey";
        public ObjectMessage objMessage;
        public string DataPath = "gameData.xml";
        public MySql mySql;
        public bool IsHave = false;
        public bool IsShow = false;
        //private System.Object tempObj;
        public void GetDataBase(string dataPath) {
            DB db = MyDataBase.GetDataBase().Connection(dataPath);
            mySql = new MySql(db);
        }
        
        public void SaveMessage(string objName)
        {
            if (mySql != null)
            {
                System.Object obj = Assembly.GetExecutingAssembly().CreateInstance(objName);
                ClassAnalyze<System.Object> tempAnalyze = new ClassAnalyze<System.Object>(obj);
                obj=tempAnalyze.GetClazz(objMessage.values);
    
                if (IsHave)
                {
                    mySql.Update(obj, defaultKey);
    
                }
                else {
                    mySql.Insert(obj, defaultKey);
                    ReadObj(objMessage.NamesOfModel[objMessage.indexOfModel]);
                }
                   
            }
        }
        public void RemoveMessage(string objName, string key)
        {
            if (mySql != null)
            {
                System.Object obj = Assembly.GetExecutingAssembly().CreateInstance(objName);
                ClassAnalyze<System.Object> tempAnalyze = new ClassAnalyze<System.Object>(obj);
                tempAnalyze.SetValue(obj, defaultKey, key);
    
                if (IsHave)
                {
                    mySql.Delete(obj, defaultKey);
                    IsHave = false;
                    ClearObjMessage();
                }
                
            }
        }
        
        public void ClearObjMessage()
        {
            for (int i = 0; i < objMessage.values.Length; i++) {
                objMessage.values[i] = "";
            }
        }
        
        public void ReadModel() {
            TextAsset[] tas = Resources.LoadAll<TextAsset>(objMessage.objectPath);
            objMessage. NamesOfModel = new string[tas.Length];
            for (int i = 0; i < tas.Length; i++) {
                objMessage.NamesOfModel[i] = tas[i].name;
            }
            
        }
        public void ReadObj(string tableName)
        {
            if(mySql!=null)
            objMessage.NamesOfObj = mySql.SelectAllObjectsName(tableName);
        }
        public void CheckData(string objName, string key)
        {
            System.Object obj = Assembly.GetExecutingAssembly().CreateInstance(objName);
            ClassAnalyze<System.Object> tempAnalyze = new ClassAnalyze<System.Object>(obj);
            tempAnalyze.SetValue(obj, defaultKey, key);
            objMessage.cols = tempAnalyze.Cols;
            obj = mySql.Select(obj, defaultKey);
            IsHave = (obj != null);
            if (IsHave)
            {
                tempAnalyze = new ClassAnalyze<System.Object>(obj);
    
    
                objMessage.values = tempAnalyze.Values;
            }
            else {
                objMessage.values = new string[objMessage.cols.Length];
            }
        }
    }
    [Serializable]
    public class ObjectMessage
    {
    
        public string objectPath = "Model";//对象所处的路径(基于Resources的相对路径)
        public string[] NamesOfModel;
        public string[] NamesOfObj;
        public int indexOfModel = 0;
        public int indexOfObj = 0;
        public string PriKey = "PriKey";
        public string[] cols;
        public string[] values;
        
    }
    复制代码

    下面这个脚本要放在Editor目录下面

    复制代码
    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    [CustomEditor(typeof(MyInspector))]
    public class EditorInspector : Editor {
        //重写展示面板
    
    
        //用户选择要加载的对象
        //提供一个主键,用户填写主键的值
        //默认主键是游戏对象名称
        //判断此对象是否已经保存在数据库中
        //如果已经存在此主键,则,加载数据到面板
        //如果没有此主键,提示用户是否创建
        //
        private SerializedObject TargetObj;
        private MyInspector MyPlane;
        private string[] shows= new string[]{"创建","加载"};
        private void InitPlane() {
            TargetObj = new SerializedObject(target);//获取编辑对象目标
            MyPlane = target as MyInspector;//转化为编辑对象
            CheckData();//检测数据
        }
    
        private void CheckData() {
            if (MyPlane.objMessage == null)//检查信息对象是否为空
            {
                MyPlane.objMessage = new ObjectMessage();//对象信息
            }
            if (MyPlane.objMessage.NamesOfModel == null || MyPlane.objMessage.NamesOfModel.Length < 1)
            {//检查对象数组
                MyPlane.ReadModel();//读取对象
            }
            if (MyPlane.objMessage.NamesOfObj == null || MyPlane.objMessage.NamesOfObj.Length < 1)
            {//检查对象数组
                MyPlane.ReadObj(MyPlane.objMessage.NamesOfModel[MyPlane.objMessage.indexOfModel]);//读取对象
            }
            if (MyPlane.objMessage.PriKey == null || MyPlane.objMessage.PriKey == "")
            {//检查对象主键名称
                //设置主键信息
                MyPlane.objMessage.PriKey = MyPlane.gameObject.name.Replace(" ", "");
            }
            if (MyPlane.mySql == null)
            {//检查数据库的连接状态
                //获取数据库连接
                 MyPlane.GetDataBase(MyPlane.DataPath);
            }
    
        }
        void OnEnable() {
    
            InitPlane();
            
        }
        
        public override void OnInspectorGUI()
        {
            
            TargetObj.Update();//更新目标数据
            
            //主键值
            //CheckData();
            int lastModel = MyPlane.objMessage.indexOfModel;
            //对象选择列表
            MyPlane.objMessage.indexOfModel = EditorGUILayout.Popup("对象组", MyPlane.objMessage.indexOfModel, MyPlane.objMessage.NamesOfModel);
            
            if (lastModel != MyPlane.objMessage.indexOfModel) { //当改变对象时,更新主键值
                //更新主键值集合
                MyPlane.ReadObj(MyPlane.objMessage.NamesOfModel[MyPlane.objMessage.indexOfModel]);
    
            }
            int lastobj = MyPlane.objMessage.indexOfObj;
            if (MyPlane.objMessage.NamesOfObj.Length > 0)
            {
                MyPlane.objMessage.indexOfObj = EditorGUILayout.Popup("对象", MyPlane.objMessage.indexOfObj, MyPlane.objMessage.NamesOfObj);
            }
            if (lastobj != MyPlane.objMessage.indexOfObj || lastModel != MyPlane.objMessage.indexOfModel)
            { //主键值集合下标改变时
                //更新主键值
                if (MyPlane.objMessage.NamesOfObj.Length>0)
                MyPlane.objMessage.PriKey = MyPlane.objMessage.NamesOfObj[MyPlane.objMessage.indexOfObj];
            }
           
    
            string lastKey = MyPlane.objMessage.PriKey;
            //显示主键文本框
            MyPlane.objMessage.PriKey = EditorGUILayout.TextField("主键", MyPlane.objMessage.PriKey);
            //路径
    
    
            string lastPath = MyPlane.DataPath;
            MyPlane.DataPath = EditorGUILayout.TextField("数据路径",MyPlane.DataPath);
            
            //判断选择的对象列表
            //更新对象信息
    
            if (MyPlane.objMessage.indexOfModel != lastModel || lastKey != MyPlane.objMessage.PriKey || lastPath != MyPlane.DataPath || lastobj != MyPlane.objMessage.indexOfObj)//改变了一些数据时重新读取数据
            {
                MyPlane.IsHave = false;//标注数据改动
    
                CheckData();//读取数据前保证系统参数无误,以及各个对象正确加载
    
                MyPlane.CheckData(MyPlane.objMessage.NamesOfModel[MyPlane.objMessage.indexOfModel], MyPlane.objMessage.PriKey);
            }
            
            //当存在时直接加载
            //当不存在时,点击创建时加载
    
            
            bool _show = MyPlane.IsShow;//记录上一次的状态
            if (MyPlane.IsHave || (MyPlane.IsShow = EditorGUILayout.Foldout(MyPlane.IsShow, shows[MyPlane.IsShow ? 1 : 0])))
            {
                if (!_show && !MyPlane.IsHave)//数据不存在而且点击了创建的时候
                { //仅执行一次,保证数据不被一直刷新而导致的无法读写
                    //当数据不存在,而且点击创建时  清除信息
    
                    MyPlane.ClearObjMessage();//清除数据的缓存
                }
            }
            //也要只进行一次的读写,保证可以进行修改操作
            if (MyPlane.IsHave || MyPlane.IsShow)//当数据存在或者点击创建时加载数据
            {
                for (int i = 0; i < MyPlane.objMessage.cols.Length; i++)
                {
                    if (MyPlane.defaultKey == MyPlane.objMessage.cols[i]) {
                        MyPlane.objMessage.values[i] = MyPlane.objMessage.PriKey;
                        continue;
                    }
                    MyPlane.objMessage.values[i] = EditorGUILayout.TextField(MyPlane.objMessage.cols[i], MyPlane.objMessage.values[i]);
    
                }
                if (GUILayout.Button("Save"))
                {
                    MyPlane.SaveMessage(MyPlane.objMessage.NamesOfModel[MyPlane.objMessage.indexOfModel]);
                }
    
                if (MyPlane.IsHave&& GUILayout.Button("Remove"))
                {
                    MyPlane.RemoveMessage(MyPlane.objMessage.NamesOfModel[MyPlane.objMessage.indexOfModel], MyPlane.objMessage.PriKey);
                    MyPlane.ReadObj(MyPlane.objMessage.NamesOfModel[MyPlane.objMessage.indexOfModel]);
                    
                }
            }
    
            
            
            TargetObj.ApplyModifiedProperties();
            
        }
    
        void show(System.Object message) {
            Debug.Log(message);
        }
    }
    复制代码

    新的xml数据存储格式:新建脚本MyXmlSql,继承DB,然后实现具体的方法:

    复制代码
    using System.Xml;
    using System.Collections.Generic;
    using System.IO;
    using System;
    
    public class MyXmlSql : DB
    {
        private XmlDocument xmlDoc;
        private string path;
        private string rootName;
        public MyXmlSql()
        {
            xmlDoc = new XmlDocument();
        }
        public MyXmlSql(string path)
        {
            xmlDoc = new XmlDocument();
            Connect(path);
        }
        public override void Connect(string path)
        {
            if (xmlDoc == null) xmlDoc = new XmlDocument();
            if (!CheckDB(path))
            {
                this.path = path;
                rootName = path.Substring(path.LastIndexOf("/")+1,path.LastIndexOf(".")- path.LastIndexOf("/")-1);
                CreateDB(rootName);
            }
            else {
                this.path = path;
                
                xmlDoc.Load(this.path);
                rootName = xmlDoc.LastChild.LocalName;
            }
        }
        public override void Close()
        {
            if (xmlDoc != null)
            xmlDoc.Save(path);
            GC.Collect();
        }
    
    
        public XmlNode CheckTable(string tableName)
        {
            XmlNode root = xmlDoc.SelectSingleNode(rootName);
            if (root.SelectSingleNode(tableName) != null) {
                return root.SelectSingleNode(tableName);
            }
    
            return CreateTable(root,tableName);
        }
        public bool CheckDB(string dBName)
        {
            return File.Exists(dBName);
        }
        public XmlNode CreateTable(XmlNode root,string tableName)
        {
            XmlNode table = xmlDoc.CreateElement(tableName);
            root.AppendChild(table);
            xmlDoc.Save(path);
            return table;
        }
        public XmlNode CreateDB(string dBName)
        {
            File.CreateText(path).Close();
            XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
            XmlNode root = xmlDoc.CreateElement(dBName);
            xmlDoc.AppendChild(xmlDeclaration);
            xmlDoc.AppendChild(root);
            xmlDoc.Save(path);
            return root;
        }
    
    
        public override bool Insert(string tableName, string[] cols, string[] values,string key)
        {
    
            if (key == null || key == "") key = values[0];
            key = key.Replace(" ","");
            XmlNode table = CheckTable(tableName);
    
            XmlNode obj = table.SelectSingleNode(key);//按照key值确定元素对象
    
            if (obj != null) {//待插入数据已经存在,插入失败
                return false;
            }
    
            XmlElement element = xmlDoc.CreateElement(key);
    
            
            for (int i = 0; i < cols.Length; i++) {
                XmlAttribute xa = xmlDoc.CreateAttribute(cols[i]);
    
                xa.Value = values[i].Replace(" ", "");
                element.Attributes.Append(xa);
                
            }
    
            
            table.AppendChild(element);
            xmlDoc.Save(path);
            return true;
        }
        public override bool Update(string tableName, string[] cols, string[] values,string key)
        {
            if (key == null || key == "") key = values[0];
            key = key.Replace(" ", "");
            XmlNode table = CheckTable(tableName);
    
            XmlNode obj = table.SelectSingleNode(key);//按照key值确定元素对象
            if (obj == null)
            {//待更新数据不存在,更新失败
                return false;
            }
            for (int i = 0; i < cols.Length; i++)
            {
                obj.Attributes[cols[i]].Value = values[i].Replace(" ", "");
    
            }
            xmlDoc.Save(path);
            return true;
    
           
        }
    
        public override bool UpdateAll(string tableName)
        {
            return false;
        }
        public override string[] Select(string tableName, string key)
        {
            XmlNode table = CheckTable(tableName);
            if (key == null || key == "") {
                if (table.ChildNodes.Count < 1) { 
                return null;
                }
                key = table.ChildNodes[0].LocalName;
            } 
            key = key.Replace(" ", "");
            
            XmlNode obj = table.SelectSingleNode(key);//按照key值确定元素对象
    
            if (obj == null) {
                return null;
            }
    
            string[] values = new string[obj.Attributes.Count]; 
    for (int i = 0; i < values.Length; i++) {
                values[i] = obj.Attributes[i].Value.Replace(" ", "");
            }
    
            return values;
        }
        public override string[] SelectAllObjectsName(string tableName)
        {
            XmlNode table = CheckTable(tableName);
            
            string[] values = new string[table.ChildNodes.Count];
    
            for (int i = 0; i < values.Length; i++) {
                values[i] = table.ChildNodes[i].LocalName;
            }
            return values;
        }
        public override List<string[]> SelectAll(string tableName)
        {
            XmlNode table = CheckTable(tableName);
            if (table.ChildNodes.Count == 0) {
                return null;
            }
            List<string[]> elements = new List<string[]>();
            for(int i=0;i<table.ChildNodes.Count;i++){//遍历表的子节点
                string[] values = new string[table.ChildNodes[i].Attributes.Count];
                for (int j = 0; j < table.ChildNodes[i].Attributes.Count; j++)
                {
                    values[j] = table.ChildNodes[i].Attributes[j].Value.Trim();
                }
                elements.Add(values);
            }
            return elements;
        }
        public override bool Delete(string tableName, string key)
        {
            XmlNode table = CheckTable(tableName);
            if (key == null || key == "") key = table.ChildNodes[0].LocalName;
            key = key.Replace(" ", "");
            
    
            XmlNode obj = table.SelectSingleNode(key);//按照key值确定元素对象
            if (obj == null)
                return false;
            obj.RemoveAll();
            table.RemoveChild(obj);
            xmlDoc.Save(path);
            return true;
        }
        public override bool DeleteAll(string tableName)
        {
            XmlNode table = CheckTable(tableName);
            table.RemoveAll();
            xmlDoc.Save(path);
            return true;
        }
        
    }
    复制代码
  • 相关阅读:
    js的原型链
    setTimeout浅析
    并行模式库PPL应用实战(一):使用task类创建并行任务
    PC客户端开发细节记录:保存GUID到VARIANT
    UWP开发细节记录:DirectX::XMMATRIX 的坑
    UWP开发细节记录:WRL::ComPtr 的坑
    UWP开发细节记录:IStream 和 IRandomAccessStream^ 以及 IMFByteStream 互转
    UWP开发细节记录:判断文件类型
    UWP开发细节记录:加载图像文件到D2D位图和D3D纹理
    基于纤程(Fiber)实现C++异步编程库(一):原理及示例
  • 原文地址:https://www.cnblogs.com/NBOWeb/p/10109610.html
Copyright © 2020-2023  润新知