流程
- 游戏对象上挂C#对接脚本,可以拖对象,C#对接脚本继承一个基类,使用xLua的Global.Get<LuaTable>("table名字")得到lua表,luaTable.Set给表注入成员,xLua还有新建表、设置元表、得到lua函数等操作。C#对接脚本用UnityAction<LuaTable>存从lua得到的生命周期函数,用luaTable.Get<UnityAction<LuaTable>>("Awake")等得到lua函数,在C#生命周期函数里执行;
- luaEnv.AddLoader增加从AB包加载lua脚本的方法,如果是安卓平台必须用UnityWebRequest异步加载则进入游戏先异步加载lua AB包在回调函数里和之后执行任何执行lua代码;
- 程序写好后把所有lua脚本后缀替换成.txt,打AB包。把从项目文件夹加载lua的方法注释掉验证从AB包加载lua成功。在编辑器里使用Android AB包加载lua没问题,只有某些粒子效果会变粉色,到Android平台就会正常;
- 测试时能明显看到初始显示的面板有一个延迟。
传递C#对象给Lua
不能在编辑器拖对象,根对象使用GameObject.Find(),子对象使用transform.Find()寻找。
function PanelMain:Open()--使用Find获得控件的笨方法
if self.obj==nil then
prefab=ABManager:LoadRes(uiAB,"PanelMain",typeof(GameObject))
self.obj=GameObject.Instantiate(prefab)
self.obj.transform:SetParent(Canvas.transform,false)
self.buttonPlay=self.obj.transform:Find("ButtonPlay"):GetComponent(typeof(Button))
self.buttonSettings=self.obj.transform:Find("ButtonSettings"):GetComponent(typeof(Button))
self.buttonRank=self.obj.transform:Find("ButtonRank"):GetComponent(typeof(Button))
self.buttonPlay.onClick:AddListener(function()
self:ClickPlay()
end)
self.buttonSettings.onClick:AddListener(function()
self:ClickSettings()
end)
self.buttonRank.onClick:AddListener(function()
self:ClickRank()
end)
else
self.obj:SetActive(true)
end
end
除此还有什么方法吗?一个C#脚本可以用luaTable.Set()给表写入成员。
luaTable = MyXLuaManager.Instance.Global.Get<LuaTable>(luaTableName);
luaTable.Set("obj",gameObject);
传递面板的控件给Lua
对于一个面板,有Image、Text、Button等组件。如果一个面板有专用的C#脚本,那么每个面板都有一个C#脚本,脚本数量增加了一倍。我尝试使用UGUI控件的共同父类UIBehaviour列表,结果lua得到的都是UIBehaviour对象,根本没有按钮的onClick这些各种控件独有的成员。
那么还想用列表注入,就还需要把具体类型传过去,但是Type不能序列化到检查器,无法在编辑器配置类型。
然后懒得设计,就给每个面板专用一个C#脚本。这些脚本的共同点是获取Lua的生命周期函数,在生命周期函数里执行,所以它们继承这样的基类。
//得到一个lua表,注入一些成员,执行它的生命周期函数
public class LuaSingleton : MonoBehaviour{
public string luaScriptName;
public string luaTableName;
protected LuaTable luaTable;
protected UnityAction awake, start, update, onDestroy;
protected void InitTable()
{
if (luaScriptName != null && luaScriptName != "")
{
MyXLuaManager.Instance.DoLuaFile(luaScriptName);
}
luaTable = MyXLuaManager.Instance.Global.Get<LuaTable>(luaTableName);
luaTable.Set("obj", gameObject);
}
protected virtual void InjectTable()
{
}
protected virtual void Awake()
{
InitTable();
awake = luaTable.Get<UnityAction>("Awake");
start = luaTable.Get<UnityAction>("Start");
update = luaTable.Get<UnityAction>("Update");
onDestroy = luaTable.Get<UnityAction>("OnDestroy");
awake?.Invoke();
}
void Start()
{
start?.Invoke();
}
void Update(){
update?.Invoke();
}
void OnDestroy()
{
onDestroy?.Invoke();
luaTable.Dispose();
}
}
各面板和基类只有注入的成员不同
public class PanelMainLua : LuaSingleton{
public Button buttonPlay,buttonSettings,buttonRank;
protected override void InjectTable()
{
base.InjectTable();
luaTable.Set(nameof(buttonPlay), buttonPlay);
luaTable.Set(nameof(buttonSettings), buttonSettings);
luaTable.Set(nameof(buttonRank), buttonRank);
}
}
然后如果加载面板由Lua完成,就变成Lua加载面板>C#脚本执行Awake()>执行Lua Awake(),里面执行初始化。这种踢皮球的流程,省去了找控件的代码,可以继续用拖拽控件,也可以执行生命周期函数。
function PanelMain:Load()
local prefab=ABManager:LoadRes(uiAB,"PanelMain",typeof(GameObject))
self.obj=GameObject.Instantiate(prefab,Canvas.transform)
end
function PanelMain:Init()
-- self.obj.transform:SetParent(,false)
self.buttonPlay.onClick:AddListener(function()
self:ClickPlay()
end)
self.buttonSettings.onClick:AddListener(function()
self:ClickSettings()
end)
self.buttonRank.onClick:AddListener(function()
self:ClickRank()
end)
end
function PanelMain.Awake()
PanelMain:Init()
end
传递多实例对象给Lua
有一个“类表”,创建一个新表,设置类表为元表。和写面板一样的思想,原来每个C#类现在充当到Lua的桥接器,C#脚本数不变,增加Lua脚本,总脚本数增加一倍。
public class LuaInstance : MonoBehaviour
{
public string luaScriptName;
public string luaClassTableName;
protected LuaTable luaClassTable, luaTable;
UnityAction awake, start, update, onDestroy;
UnityAction<LuaTable,GameObject>onTriggerEnter;
protected virtual void InjectObjects()
{
}
void Awake()
{
if (luaScriptName != null && luaScriptName != "")
{
MyXLuaManager.Instance.DoLuaFile(luaScriptName);
}
luaClassTable = MyXLuaManager.Instance.Global.Get<LuaTable>(luaClassTableName);
luaTable = MyXLuaManager.Instance.luaEnv.NewTable();
luaTable.SetMetaTable(luaClassTable);
luaTable.Set("obj",gameObject);
InjectObjects();
awake = luaClassTable.Get<UnityAction>("Awake");
start = luaClassTable.Get<UnityAction>("Start");
update = luaClassTable.Get<UnityAction>("Update");
onTriggerEnter=luaClassTable.Get<UnityAction<LuaTable,GameObject>>("OnTriggerEnter");
onDestroy = luaC

最低0.47元/天 解锁文章
2523

被折叠的 条评论
为什么被折叠?



