Unity编辑器开发笔记

上方菜单

cs 复制代码
[MenuItem("工具栏选项名")]
    static void XXX(){
}

弹窗

下面演示了在弹窗上点击一个按钮,出现文件浏览器,且只显示xlsx文件,很有用。

cs 复制代码
public class PopWindow : EditorWindow
{
    [MenuItem("我的工具/弹窗")]
    static void OpenWindow(){
        GetWindow<PopWindow>(false,"我的弹窗",true);
    }
    void OnGUI(){
        EditorGUILayout.LabelField("Excel路径", ExcelPath);
        if (GUILayout.Button("选择Excel文件"))
        {
            ExcelPath = EditorUtility.OpenFilePanel("选择Excel文件",
                Application.dataPath + "/..", "xlsx");
        }
    }
    static string ExcelPath;
}

自定义检查器

cs 复制代码
[CustomEditor(typeof(XXX))]

public class MyXXXEditor : Editor
{
    XXX _component;
    void OnEnable(){
        _component=target as XXX;
    }
    void OnDisable(){
        _component=null;
    }
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
    }
}

Hierarchy窗口增加选项

cs 复制代码
[MenuItem("GameObject/选项")]
    static void XXX(){
}

Project窗口增加选项

cs 复制代码
[MenuItem("Assets/选项")]
    static void XXX(){
}

在Add Component菜单增加选项

cs 复制代码
[AddComponentMenu("选项/选项2")]
public class XXX:MonoBehaviour{

}

在组件右键菜单增加选项

cs 复制代码
[MenuItem("CONTEXT/脚本名/选项")]
    static void XXX(){
}

Excel导表工具(弹窗式)

生成C#数据类,把Excel配表二进制序列化存储

cs 复制代码
using Excel;
using Mercenaria;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.IO.Pipes;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using UnityEditor;
using UnityEngine;
using static UnityEngine.EventSystems.EventTrigger;
using static UnityEngine.Rendering.DebugUI;

public class MyExcelTool : EditorWindow
{
    [MenuItem("我的工具/Excel导表工具")]
    static void OpenWindow(){
        GetWindow<MyExcelTool>(false, "Excel导表工具", true);
    }
    void OnGUI() {
        EditorGUILayout.LabelField("Excel路径", ExcelPath);
        if (GUILayout.Button("选择Excel文件"))
        {
            ExcelPath = EditorUtility.OpenFilePanel("选择Excel文件",
                Application.dataPath + "/..", "xlsx");
        }
        NAMESPACE = EditorGUILayout.TextField("命名空间", NAMESPACE);
        FieldNameRow = EditorGUILayout.IntField("变量名所在行", FieldNameRow);
        TypeRow = EditorGUILayout.IntField("类型所在行", TypeRow);
        KeyMarkRow = EditorGUILayout.IntField("key标记所在行", KeyMarkRow);
        ContentStartRow = EditorGUILayout.IntField("内容开始行", ContentStartRow);
        DataClassName = EditorGUILayout.TextField("数据类名", DataClassName);
        OutputCsPath = EditorGUILayout.TextField("数据类生成路径", OutputCsPath);
        if (GUILayout.Button("生成C#数据类"))
        {
            GenerateDataClass();
        }
        OutputBinPath = EditorGUILayout.TextField("二进制导出路径", OutputBinPath);
        if (GUILayout.Button("Excel表导出为自定义二进制"))
        {
            ExcelToBin();
        }
        if (GUILayout.Button("生成对话配置文件"))
        {
            ExportTalk();
        }
        if (GUILayout.Button("读取并打印对话配置文件"))
        {
            PrintTalk();
        }
    }
    static int FieldNameRow = 0;//第几行是字段名
    static int TypeRow = 1;//第几行是类型名
    static int KeyMarkRow = 2;//第几行标记key
    static int ContentStartRow = 4;//从第几行数据开始
    static string ExcelPath;
    static string OutputBinPath = Application.streamingAssetsPath + "/Config";
    static string OutputCsPath = $"{Application.dataPath}/Scripts/Data1.cs";
    static string NAMESPACE = "Mercenaria";
    static string DataClassName;
    static void ExcelToBin()
    {
        using (FileStream excelStream = File.Open(ExcelPath,
            FileMode.Open, FileAccess.Read),
            outputStream = new FileStream
            (OutputBinPath, FileMode.OpenOrCreate, FileAccess.Write))
        {
            IExcelDataReader reader = ExcelReaderFactory.CreateOpenXmlReader(excelStream);
            DataSet dataSet = reader.AsDataSet();
            DataTable table = dataSet.Tables[0];
            int dataRowNum = table.Rows.Count - ContentStartRow;
            outputStream.Write(BitConverter.GetBytes(dataRowNum), 0, 4);
            DataRow fieldRow = table.Rows[FieldNameRow];
            DataRow typeRow = table.Rows[TypeRow];
            DataRow row;
            for (int i = ContentStartRow; i < table.Rows.Count; i++)
            {
                row = table.Rows[i];
                for (int j = 0; j < table.Columns.Count; j++)
                {
                    string val = row[j].ToString();
                    Debug.Log(val);
                    switch (typeRow[j].ToString())
                    {
                        case "int":
                            outputStream.Write(
                                BitConverter.GetBytes(int.Parse(val)), 0, 4);
                            break;
                        case "float":
                            outputStream.Write(
                                BitConverter.GetBytes(float.Parse(val)), 0, 4);
                            break;
                        case "bool":
                            outputStream.Write(BitConverter.GetBytes(bool.Parse(val)), 0, 1);
                            break;
                        case "string":
                            StringToStream(outputStream, val);
                            break;
                    }
                }
            }
            outputStream.Close();
            excelStream.Close();
            AssetDatabase.Refresh();
        }
    }
    static void GenerateDataClass()
    {
        using (FileStream excelStream = File.Open(ExcelPath,
            FileMode.Open, FileAccess.Read))
        {
            IExcelDataReader reader = ExcelReaderFactory.CreateOpenXmlReader(excelStream);
            DataSet dataSet = reader.AsDataSet();
            DataTable table = dataSet.Tables[0];
            DataRow fieldRow = table.Rows[FieldNameRow];
            DataRow typeRow = table.Rows[TypeRow];
            string className = DataClassName == null || DataClassName == "" ? table.TableName : DataClassName;
            StringBuilder builder = new StringBuilder($"namespace {NAMESPACE}{{\n\tpublic class {className}{{\n");
            for (int i = 0; i < table.Columns.Count; i++)
            {
                builder.Append($"\t\tpublic {typeRow[i]} {fieldRow[i]};\n");
            }
            builder.Append("\t}\n}");
            File.WriteAllText(OutputCsPath, builder.ToString());
            excelStream.Close();
        }
        AssetDatabase.Refresh();
    }
    static void StringToStream(Stream stream, string str)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(str);
        stream.Write(BitConverter.GetBytes(bytes.Length), 0, 4);
        stream.Write(bytes, 0, bytes.Length);
    }
    [MenuItem("我的工具/读取配置")]
    static void ReadConfig()
    {
        Dictionary<int, GunConfigEx> dic = MyConfigManager.Instance.LoadConfig<GunConfigEx>(
            MyConfigManager.OutputPath);
        foreach (KeyValuePair<int, GunConfigEx> pair in dic)
        {
            Debug.Log(pair.Value.name);
            Debug.Log(pair.Value.desc);
        }
    }
    static void ExportTalk()
    {
        using (FileStream excelStream = File.Open(ExcelPath,
            FileMode.Open, FileAccess.Read),
            outputStream = new FileStream
            (OutputBinPath, FileMode.OpenOrCreate, FileAccess.Write))
        {
            IExcelDataReader reader = ExcelReaderFactory.CreateOpenXmlReader(excelStream);
            DataSet dataSet = reader.AsDataSet();
            Debug.Log($"读取Excel{reader},它有{dataSet.Tables.Count}个sheet");
            TalkConfig talkConfig = new TalkConfig();
            for (int i = 0; i < dataSet.Tables.Count; i++)
            {//一个sheet是一段对话
                DataTable table = dataSet.Tables[i];
                if (!talkConfig.talkDic.ContainsKey(table.TableName))
                {
                    List<SentenceEntry>sentences= new List<SentenceEntry>();
                    DataRow row;
                    Debug.Log(table.Rows.Count);
                    for (int j = ContentStartRow; j < table.Rows.Count; j++)
                    {
                        row = table.Rows[j];
                        SentenceEntry entry = new SentenceEntry();
                        //这样赋值写,通过报错能看出哪个字段失败了。直接初始化不行
                        entry.id = int.Parse(row[0].ToString());
                        entry.NPCWords = row[1].ToString();
                        entry.Reply = row[2].ToString();
                        entry.AudioClip = row[3].ToString();
                        entry.AnimClip = row[4].ToString();
                        entry.LookAtPlayer = bool.Parse(row[5].ToString());
                        entry.JumpTo = int.Parse(row[6].ToString());
                        entry.EventName = row[7].ToString();
                        sentences.Add(entry);
                    }
                    talkConfig.talkDic.Add(table.TableName, sentences);
                    Debug.Log($"对话{table.TableName}导出{table.Rows.Count- ContentStartRow}句话");
                }
            }
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            binaryFormatter.Serialize(outputStream, talkConfig);
            outputStream.Close();
            excelStream.Close();
            AssetDatabase.Refresh();
            Debug.Log("对话配置导出完毕");
        }
    }
    static void PrintTalk()
    {
        TalkConfig talkConfig = new TalkConfig();
        using (FileStream fileStream = new FileStream(OutputBinPath,
        FileMode.Open, FileAccess.Read))
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            talkConfig = binaryFormatter.Deserialize(fileStream) as TalkConfig;
            fileStream.Close();
        }
        Debug.Log(talkConfig.talkDic.Count);
        foreach (KeyValuePair<string, List<SentenceEntry>> pair in talkConfig.talkDic)
        {
            Debug.Log(pair.Key);
            for (int i = 0; i < pair.Value.Count; i++)
            {
                Debug.Log(pair.Value[i].NPCWords);
            }
        }
    }
}
相关推荐
allbs2 小时前
spring boot项目excel导出功能封装——3.图表导出
spring boot·后端·excel
lqz19935 小时前
根据html导出excel和word
html·word·excel
12程序猿5 小时前
postman调用文件(.xlsm---带宏的excel文件)下载接口成功下载excel文件,浏览器访问下载文件打不开
excel·lua·postman
霜绛6 小时前
Unity:lua热更新(三)——Lua语法(续)
unity·游戏引擎·lua
世洋Blog14 小时前
更好的利用ChatGPT进行项目的开发
人工智能·unity·chatgpt
刻BITTER18 小时前
用EXCEL 将单色屏幕的Bitmap 字模数据还原回图形
单片机·嵌入式硬件·excel·arduino
匿者 衍18 小时前
POI读取 excel 嵌入式图片(支持wps 和 office)
java·excel
天外天-亮18 小时前
Vue + excel下载 + 水印
前端·vue.js·excel
ganshenml20 小时前
sed 流编辑器在前端部署中的作用
前端·编辑器