[开发工具]预制件转LUA

一、实现效果

通过工具将Prefab转换成Lua模板相对应的Lua文件,提高开发速度。

1、预制件结构

2、转换的Lua文件

3.Lua的文件内容

TestPanel = BaseClass(LuaUI)

function TestPanel:__init( ... )		
	self:__property(...)
	self:Config()
	self:InitEvent()
end

function TestPanel:SetProperty( ... )

end

function TestPanel:Config()
	
end

function TestPanel:RegistUI( ui )
	if ui then
		self:SetUI(ui)
	else
		UIMgr.CreateUI("test","TestPanel",UIMgr.UIGroupEnum.Common,function (uiObj)
			self:SetUI(uiObj)
		end)		
	end		

	--UIComponent
	self.Image_1= self.ui.transform:Find("Image_1"):GetComponent("Image")
	self.Button_Open= self.ui.transform:Find("Button_Open"):GetComponent("Button")
	self.Button_UIPolygon= self.ui.transform:Find("Button_UIPolygon"):GetComponent("Button")

	
end

function TestPanel:InitEvent()	
	--local Event
	--self.handle=self.mode:AddEventListener(TestConst.Event,function ()
	--	self:InitPanel()
	--end)
	
	--Global Event
	--self.handle2=GlobalDispatcher:AddEventListener(EventName.TestEvent,function ()
	--	print("GlobalDispatcher")
	--end)
	
	--Button Click Event
	--self.Btn_Open.onClick:AddListener(function ()
	--			TestPanel:RefreshPanel()
	--		end)
end

function TestPanel:RemoveEvent()
	
end

function TestPanel.Create( ui, ...)
	return TestPanel.New(ui, "#", {...})
end

function TestPanel:__delete()
	TestPanel:RemoveEvent()	
end

二、思路

1.预制件Prefab在Unity里其实是个文本,里面存放的是相关联的组件GUID、结构信息等等。

2.通过解析Prefab,对其文本内容进行操作。

3.通过创建Lua模板来合成所需要相对应的Lua文件

4.定义命名规则,约束替换规则。

流程:创建Lua模板->创建预制件->读取预制件内容->创建空Lua文件->写入Lua模板内容->根据预制件内容对Lua进行替换操作->保存。

三、脚本

1、我的Lua模板(根据需求定制)

UIName = BaseClass(LuaUI)

function UIName:__init( ... )		
	self:__property(...)
	self:Config()
	self:InitEvent()
end

function UIName:SetProperty( ... )

end

function UIName:Config()
	
end

function UIName:RegistUI( ui )
	if ui then
		self:SetUI(ui)
	else
		UIMgr.CreateUI("ABName","UIName",UIMgr.UIGroupEnum.Common,function (uiObj)
			self:SetUI(uiObj)
		end)		
	end		

	--UIComponent
	
end

function UIName:InitEvent()	
	--local Event
	--self.handle=self.mode:AddEventListener(TestConst.Event,function ()
	--	self:InitPanel()
	--end)
	
	--Global Event
	--self.handle2=GlobalDispatcher:AddEventListener(EventName.TestEvent,function ()
	--	print("GlobalDispatcher")
	--end)
	
	--Button Click Event
	--self.Btn_Open.onClick:AddListener(function ()
	--			TestPanel:RefreshPanel()
	--		end)
end

function UIName:RemoveEvent()
	
end

function UIName.Create( ui, ...)
	return UIName.New(ui, "#", {...})
end

function UIName:__delete()
	UIName:RemoveEvent()	
end

2.替换规则

UIName:自动替换成预制名的名称,形成Lua文件类名

ABName:自动替换成AssetBundle的名称,我的工程有时候AB包的层次会分很多层,所以需要指定名称。

3.命名规则及自动生成引用

预制件需要在Lua中生成引用的字段的组件,需要遵循:引用的组件名_对象名(Button_Open)

这是为了自动生成Lua中的引用:

self.Button_Open= self.ui.transform:Find("Button_Open"):GetComponent("Button")

为了确定在哪个位置生成引用,我在模板中写了一个注释:--UIComponent,用来标记生成文本的位置

4.编辑器脚本

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;

public class LuaUtility
{
    [MenuItem("Tool/Lua Script Tool/To LuaUI")]
    public static void OpenWindow()
    {
        Rect wr = new Rect(0, 0, 380, 150);
        LuaToolEditor window = (LuaToolEditor)EditorWindow.GetWindowWithRect(typeof(LuaToolEditor), wr, true, "Lua转换工具");
        window.Show();
    }

    //将UI预制件转换成Lua UI 脚本
    [MenuItem("CONTEXT/RectTransform/To LuaUI")]
    private static void ToLuaUI()
    {
        Rect wr = new Rect(0, 0, 380, 150);
        LuaToolEditor window = (LuaToolEditor)EditorWindow.GetWindowWithRect(typeof(LuaToolEditor), wr, true, "Lua转换工具");
        window.Show();
    }

    //读取Prefab的文本内容
    public static void ToLuaUIScript(string assetBundleName)
    {
        //单个选中
        string path = AssetDatabase.GetAssetPath(Selection.activeObject);

        //以文本方式读取预制件
        if (path.EndsWith(".prefab"))
        {
            string text = File.ReadAllText(path);
            List<string> ChildNameList = new List<string>();

            //查找prefab下的child引用
            int Index = 1;

            while (Index != -1)
            {
                Index = text.IndexOf("m_Name");

                if (Index != -1)
                {
                    text = text.Substring(Index);
                }
                else
                {
                    break;
                }

                Index = text.IndexOf('\n');
                if (Index != -1)
                {
                    int LastIndex = Index - 8;
                    string ChildName = text.Substring(8, LastIndex);

                    if (ChildName != "" && ChildName != Selection.activeObject.name)
                    {
                        ChildNameList.Add(text.Substring(8, LastIndex));
                    }

                    text = text.Substring(Index + 1);
                }
            }

            WriteLuaUIFile(@"Assets/DevelopRes/LuaUI/LuaUITemplate.txt", Selection.activeObject.name, ChildNameList,assetBundleName);
        }
    }

    private static void WriteLuaUIFile(string templatePath, string fileName,List<string> childNameList,string assetBundleName)
    {
        //创建StreamWriter对象
        StreamWriter m_SW = new StreamWriter(@"Assets/DevelopRes/LuaUI/"+ fileName+".lua");

        //读取模板文本
        string text = File.ReadAllText(templatePath);

        //替换模板文本中指定字符串
        text = text.Replace("UIName", fileName);
        text = text.Replace("ABName", assetBundleName.ToLower());

        //组合Child字符串
        StringBuilder stringBuilder = new StringBuilder();
        foreach(string ChidName in childNameList)
        {
            string[] StrArray = ChidName.Split('_');

            if(StrArray.Length>1)
            {
                string forStr = System.String.Format("\tself.{0}= self.ui.transform:Find(\"{1}\"):GetComponent(\"{2}\")\n", ChidName, ChidName, StrArray[0]);
                stringBuilder.Append(forStr);
            }         
        }

        //定位插入UI引用字符串的位置
        int insertIndex=text.IndexOf("UIComponent");

        if (insertIndex != -1 || stringBuilder.Equals(""))
        {
            text=text.Insert(insertIndex+11, "\n"+stringBuilder.ToString());          
            m_SW.Write(text);
        }
        else
        {
            m_SW.Write(text);
        }

        //关闭Lua文件
        m_SW.Close();
    }
}

[CustomEditor(typeof(DefaultAsset))]
public class LuaToolEditor : EditorWindow
{
    string text = "";
    public void Awake()
    {
       
    }
        //绘制窗口时调用
    void OnGUI()
    {
        GUI.Label(new Rect(20, 30, 300, 50), "LuaUI命名规范:\nChild的为组件名_自定义对象名,会自动在LuaUI中生成引用");
        
        输入框控件
        text = EditorGUILayout.TextField("关联的AssetBundle名:", text);

        if (GUI.Button(new Rect(20, 60, 150, 30), "转换LuaUI"))
        {
            LuaUtility.ToLuaUIScript(text);
            //关闭窗口
            this.Close();
        }

        if (GUI.Button(new Rect(20, 110, 190, 30), "转换CommonBackgroundUI"))
        {
            LuaUtility.ToLuaUIScript(text);
            //关闭窗口
            this.Close();
        }

        if (GUI.Button(new Rect(200, 60, 150, 30), "关闭窗口"))
        {
            //关闭窗口
            this.Close();
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值