IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> unity学习笔记之不通过路径通过拖拽获取lua脚本里定义的UI组件 -> 正文阅读

[游戏开发]unity学习笔记之不通过路径通过拖拽获取lua脚本里定义的UI组件

哇这简直是个革命性的功能!先感谢一下某位不愿意透露姓名的贝贝大佬提供的想法和技术支持!

先简述一下这是个啥功能,就是我们项目之前在lua里获取UI组件都是通过路径来获取,

类似这种,定义的时候需要每个组件都复制路径不方便而且容易出错就不说了,这几天美术在重新设计原有的一些UI界面,各种调整物体父节点或者更换预制体,每次美术那边动一次都需要程序这边更改路径名字,真的挺烦,于是在大佬提示下,我这边就实现了一个可以读取lua里定义的组件,然后像C#一样直接把组件拖拽进框框里就可以了的脚本,像这样:

(这是lua里定义的组件)?

?

这是在脚本里解析之后,就可以直接把目标组件拖拽进来,更改路径啥的再也不用动代码了!鼓掌!撒花!

接下来说说具体实现过程。

大佬教的,做一个大功能需要拆分成一个个的小需求。上面这些拆成小需求就是?首先读目标lua文件的路径,然后解析定义好的字符串,把字符串转换成对应的组件类型,然后再在编辑器面板里显示出来就可以啦。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Text.RegularExpressions;
using System;
using UnityEngine.UI;
using SLG.UI;
using TMPro;

namespace Game.UI
{

    [System.Serializable]
    public class LuaUIComponentParams
    {
        public string key;
        public string componentType;
        public string node;
        public UnityEngine.Object obj;
        //public GameObject gameObject;
    }

    public class LuaUIComponent : MonoBehaviour
    {
        public string luaPath = "";
        public string paramsName = "ComponentParams";


        [HideInInspector]
        public List<LuaUIComponentParams> paramsList;

        public void ReadLuaUIComponentParams(string path)
        {
            Debug.Log(path);
            string text = File.ReadAllText(path);
            text = DeleteLog(text);
            text = text.Replace("\n", "");
            text = text.Replace("\r", "");
            text = text.Replace(" ", "");
            text = text.Replace("\"", "");
            text = CutOutStr(text, paramsName + "={", "}");
            convertStrToList(text);
            //Debug.Log(paramsList);

        }

        //获取指定的字符串区间
        private string CutOutStr(string source, string startStr = "", string endStr = "")
        {
            Regex rg;
            if (endStr.Equals(""))
            {
                rg = new Regex("(?<=(" + startStr + "))[.\\s\\S]*");
            }
            else if (startStr.Equals(""))
            {
                rg = new Regex(".*?(?=(" + endStr + "))");
            }
            else
            {
                rg = new Regex("(?<=(" + startStr + "))[.\\s\\S]*?(?=(" + endStr + "))");
            }
            return rg.Match(source).Value;
        }

        //删除注释
        private string DeleteLog(string text)
        {
            Regex stringReg = new Regex("(\".*?)--(.*?\")(.*?\n)");

            var ms = stringReg.Matches(text);

            for (int i = 0; i < ms.Count; i++)
            {
                string newString = ms[i].Value.Replace('-', '?');
                text = text.Replace(ms[i].Value, newString);
            }

            stringReg = new Regex("(\'.*?)--(.*?\')(.*?\n)");

            ms = stringReg.Matches(text);
            //if (ms.Count > 0)
            //{
            //    Debug.Log(file);
            //}
            for (int i = 0; i < ms.Count; i++)
            {
                string newString = ms[i].Value.Replace('-', '?');
                text = text.Replace(ms[i].Value, newString);
            }



            Regex reg = new Regex(@"--\[[\c\=]*\[[\s\S]*?\][\c\=]*\]|--[\s\S]*?\n");
            text = reg.Replace(text, "\n");

            stringReg = new Regex("(\".*?)(.*?\")(.*?\n)");

            ms = stringReg.Matches(text);
            for (int i = 0; i < ms.Count; i++)
            {
                string newString = ms[i].Value.Replace('?', '-');
                // Debug.Log(newString);

                text = text.Replace(ms[i].Value, newString);
            }

            stringReg = new Regex("(\'.*?)(.*?\')(.*?\n)");

            ms = stringReg.Matches(text);
            for (int i = 0; i < ms.Count; i++)
            {
                string newString = ms[i].Value.Replace('?', '-');
                // Debug.Log(newString);

                text = text.Replace(ms[i].Value, newString);
            }
            return text;
        }

        //解析指定字符串,转化成List
        private void convertStrToList(string str)
        {
            string[] array = str.Split(',');
            List<LuaUIComponentParams> result = new List<LuaUIComponentParams>();
            foreach (var content in array)
            {
                string[] arr = content.Split(':');
                if (arr.Length < 2)
                {
                    continue;
                }
                LuaUIComponentParams lcp = new LuaUIComponentParams();
                lcp.key = arr[0];
                lcp.componentType = arr[1];
                // lcp.component = convertStrToType(lcp.componentType);
                lcp.node = arr[2];

                var oldLcp = getLcpFromList(lcp.key, lcp.componentType);

                Debug.Log(lcp.key + "   " + lcp.componentType);
                if (oldLcp != null)
                {
                    lcp.obj = oldLcp.obj;
                }
                result.Add(lcp);

            }
            paramsList = result;
        }

        //获取原有List里的数据
        private LuaUIComponentParams getLcpFromList(string key, string componentType)
        {
            foreach (var param in paramsList)
            {
                if (param.key == key && param.componentType == componentType)
                {
                    return param;
                }
            }
            return null;
        }

        //private 
    }
}

这是组件部分的逻辑

然后是编辑器部分的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using System;
using SLG.UI;
using TMPro;

namespace Game.UI
{
    [CustomEditor(typeof(LuaUIComponent))]
    public class LuaUIComponentEditor : Editor
    {

        public override void OnInspectorGUI()
        {
            DrawDefaultInspector();

            LuaUIComponent lc = (LuaUIComponent)target;
            if (GUILayout.Button("读取组件"))
            {
                string prvPath = Application.dataPath + "/../../../client/project_s_client/game_assets/scripts/ui/";
                string endPath = ".lua";
                string path = prvPath + lc.luaPath + endPath;
                lc.ReadLuaUIComponentParams(path);

            }
            if (lc.paramsList != null && lc.paramsList.Count > 0)
            {
                EditorGUILayout.BeginVertical();
                foreach (var param in lc.paramsList)
                {
                    param.obj = EditorGUILayout.ObjectField(param.key, param.obj, convertStrToType(param.componentType), null);

                }

                EditorGUILayout.EndVertical();
            }

            if (GUI.changed)
            {

                EditorUtility.SetDirty(target);
                AssetDatabase.SaveAssets();
                EditorUtility.ClearDirty(target);
            }

        }

        private Type convertStrToType(string str)
        {
            switch (str)
            {
                case "Transform":
                    return typeof(Transform);
                case "RectTransform":
                    return typeof(RectTransform);
                case "Button":
                    return typeof(Button);
                case "Image":
                    return typeof(Image);
                case "GameObject":
                    return typeof(GameObject);
                case "UIScrollRect":
                    return typeof(UIScrollRect);
                case "UIImage":
                    return typeof(UIImage);
                case "TextMeshPro":
                    return typeof(TextMeshProUGUI);
                case "TMP_InputField":
                    return typeof(TMP_InputField);
                case "Input":
                    return typeof(TMP_InputField);
                case "Toggle":
                    return typeof(Toggle);
                case "Slider":
                    return typeof(Slider);
                default:
                    return typeof(GameObject);
            }
        }


    }
}

比较一目了然也没啥好说的,编辑器脚本不用太考虑性能,所以获取组件部分暴力switch就可以啦。

这个地方有一个知识点:unity监测改变是脏标记模式,改变在被用到的时候才会被监测到,所以如果不自己setDirty的话拖入组件是不会被被监测到改变的~

今天的笔记就到这里~希望可以帮到看到这篇笔记的大家~~

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-06-29 19:25:12  更:2022-06-29 19:25:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/19 14:59:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码