使用的是XLua插件
当为某个页面编写视图脚本,并且希望这个视图脚本用Lua语言来写的时候,通过以下方案调用Lua脚本,这个C#脚本要挂载在某个Ui物体上:
using System;
using UnityEngine;
using System.Collections;
using XLua;
using XLuaFramework;
[LuaCallCSharp]
public class LuaBehaviour : MonoBehaviour
{
[CSharpCallLua]
private delegate void delLuaAwake(GameObject obj);
LuaBehaviour.delLuaAwake luaAwake;
[CSharpCallLua]
private delegate void delLuaStart();
LuaBehaviour.delLuaStart luaStart;
[CSharpCallLua]
private delegate void delLuaUpdate();
LuaBehaviour.delLuaUpdate luaUpdate;
[CSharpCallLua]
private delegate void delLuaOnDestroy();
LuaBehaviour.delLuaOnDestroy luaOnDestroy;
private LuaTable scriptEnv;
private LuaEnv luaEnv;
public string Tag;
void Awake()
{
luaEnv = LuaManager.luaEnv; //此处要从LuaManager上获取 全局只有一个
scriptEnv = luaEnv.NewTable();
LuaTable meta = luaEnv.NewTable();
meta.Set("__index", luaEnv.Global);
scriptEnv.SetMetaTable(meta);
meta.Dispose();
string luaScriptFileName = name; //luaScriptFileName 对应的是lua脚本的名字
if (luaScriptFileName.Contains("(Clone)"))
{
luaScriptFileName = luaScriptFileName.Split(new string[] { "(Clone)" }, StringSplitOptions.RemoveEmptyEntries)[0];
}
luaScriptFileName = luaScriptFileName.Replace("pan_", "");
Debug.Log(luaScriptFileName);
luaAwake = scriptEnv.GetInPath<LuaBehaviour.delLuaAwake>(luaScriptFileName + ".awake");
luaStart = scriptEnv.GetInPath<LuaBehaviour.delLuaStart>(luaScriptFileName + ".start");
luaUpdate = scriptEnv.GetInPath<LuaBehaviour.delLuaUpdate>(luaScriptFileName + ".update");
luaOnDestroy = scriptEnv.GetInPath<LuaBehaviour.delLuaOnDestroy>(luaScriptFileName + ".ondestroy");
scriptEnv.Set("self", this);
if (luaAwake != null)
{
luaAwake(gameObject);
}
}
void Start()
{
if (luaStart != null)
{
luaStart();
}
}
void Destroy()
{
if (luaOnDestroy != null)
{
luaOnDestroy();
}
luaOnDestroy = null;
luaUpdate = null;
luaStart = null;
}
}
或者:
/***
*
* Title: “纯lua框架”,C#与lua文件映射调用
*
* 主要功能:
* 使得"UI预设"同名的lua文件,自动获取常用的unity生命周期函数
* (eg: Awake()、Start()、Update()....)
*
* Description:
* 详细描述:
* 使用委托技术,与特定的(lua文件)lua函数,进行映射。
*
*
* Date: 2019
*
* Version: 0.1
*
* Modify Recoder:
*
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using XLua;
namespace LuaFramework
{
public class BaseLuaUIForm : MonoBehaviour
{
//定义委托
[CSharpCallLua]
public delegate void delLuaStart(GameObject go);
//声明委托
BaseLuaUIForm.delLuaStart luaStart;
[CSharpCallLua]
public delegate void delLuaAwake(GameObject go);
BaseLuaUIForm.delLuaAwake luaAwake;
[CSharpCallLua]
public delegate void delLuaUpdate(GameObject go);
BaseLuaUIForm.delLuaUpdate luaUpdate;
[CSharpCallLua]
public delegate void delLuaDestroy(GameObject go);
BaseLuaUIForm.delLuaDestroy luaDestroy;
//定义lua表
private LuaTable luaTable;
//定义lua环境
private LuaEnv luaEnv;
private void Awake()
{
//得到lua的环境
luaEnv = LuaHelper.GetInstance().GetLuaEnv();
/* 设置luaTable 的元方法 (“__index”) */
luaTable = luaEnv.NewTable();
LuaTable tmpTab = luaEnv.NewTable();//临时表
tmpTab.Set("__index", luaEnv.Global);
luaTable.SetMetaTable(tmpTab);
tmpTab.Dispose();
/* 得到当前脚本所在对象的预设名称,且去除后缀(["(Clone)"]) */
string prefabName = this.name; //当前脚本所挂载的游戏对象的名称
if (prefabName.Contains("(Clone)"))
{
prefabName = prefabName.Split(new string[] { "(Clone)" }, StringSplitOptions.RemoveEmptyEntries)[0];
}
/* 查找指定路径下lua文件中的方法,映射为委托 */
luaAwake = luaTable.GetInPath<BaseLuaUIForm.delLuaAwake>(prefabName + ".Awake");
luaStart = luaTable.GetInPath<BaseLuaUIForm.delLuaStart>(prefabName + ".Start");
luaUpdate = luaTable.GetInPath<BaseLuaUIForm.delLuaUpdate>(prefabName + ".Update");
luaDestroy = luaTable.GetInPath<BaseLuaUIForm.delLuaDestroy>(prefabName + ".OnDestroy");
//调用委托
if (luaAwake != null)
{
luaAwake(gameObject);
}
}
void Start()
{
//调用委托
if (luaStart!=null)
{
luaStart(gameObject);
}
}
private void Update()
{
if (luaUpdate != null)
{
luaUpdate(gameObject);
}
}
private void OnDestroy()
{
if (luaDestroy != null)
{
luaDestroy(gameObject);
}
luaAwake = null;
luaStart = null;
luaUpdate = null;
luaDestroy = null;
}
}//Class_end
}//namespace_end
对应的Lua脚本:
UIRootView = {}
local this = UIRootView;
local transform;
local gameObject;
function UIRootView.awake(obj)
gameObject = obj;
transform = obj.transform;
this.InitView();
print('UIRootView awake');
end
--初始化面板--
function UIRootView.InitView()
this.btnOpenMessage = transform:Find("Canvas/ContainerBottomRight/btnOpenMessage");
this.btnOpen=this.btnOpenMessage:GetComponent("UnityEngine.UI.Button");
--this.btnOpen.onClick:AddListener(this.OpenMessageClick);
--也可以写成如下匿名函数的回调
-- --[[
this.btnOpen.onClick:AddListener(
function ()
GameInit.LoadView(CtrlNames.MessageCtrl);
end
);
-- --]]
end
--单击事件--
function UIRootView.OpenMessageClick()
print("点击了打开消息按钮");
GameInit.LoadView(CtrlNames.MessageCtrl);
end
function UIRootView.start()
print('UIRootView start');
end
function UIRootView.update()
end
function UIRootView.ondestroy()
end