一、实现效果
通过工具将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();
}
}
}