当前位置:Gxlcms > 数据库问题 > unity编辑器xml数据库插件

unity编辑器xml数据库插件

时间:2021-07-01 10:21:17 帮助过:8人阅读

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);
    }
}

部分源码如上。省去了一些源码和路径加载等东西。如果想要完整版,可以联系我。

 本文地址:http://www.cnblogs.com/jqg-aliang/p/4767026.html

unity编辑器xml数据库插件

标签:

人气教程排行