准备(前置条件):
Xlua相关文件已导入工程,已经能够进行patchfile热更修改

一、C#写一个 LuaWindow 基类

包含3个步骤:

1.读入lua文件:

public static bool LoadLuaScript(string windowName)
{
	if(!mLuaWindowFileDic.ContainsKey(windowName))
	{
		if(!LoadXLuaFile("..."+".byte")) //读入xlua文件
			return false;
		mLuaWindowFileDic.Add(windowName, 1);
	}
	return true;
}
	
public static LoadXLuaFile(string LuaPath)
{
	string luaScript = ReadFile(LuaPath); //这里省略把lua代码读入内存的实现
	if(!string.IsNullOrEmpty(luaScript))
	{
		LuaEnv.DoString(luaScript, LuaPath); //Lua虚拟机执行代码
		return true;
	}
	return false;
}

2.加载Lua新增的窗口及初始化函数
在入口处添加LuaWindow的初始化:

LuaWindow luaWnd = new LuaWindow();
luaWnd.InitLuaFunctions(para.windowName);

初始化函数实现:

public void InitLuaFunctions(string windowName)
{
	object obj = XLuaEnv.Global.Get<object>(windowName);
	LuaTable table = obj as LuaTable;

	luaFunc_Awake = GetLuaFunctionFromTable("Awake", windowName, table);
	luaFunc_Start = GetLuaFunctionFromTable("Start", windowName, table);
	luaFunc_Update = GetLuaFunctionFromTable("Update", windowName, table);
}

public static LuaFunction GetLuaFunctionFromTable(string functionName, string windowName, LuaTable table)
{
	LuaFunction func = null;
	string strKey = tableName + table.ToString() + "." + functionName;
	if(!mLuaFunctionDic.TryGetValue(strKey, out func))
	{
		func = table.Get<LuaFunction>(functionName);
		if(func != null)
		{
			mLuaFunctionDic.Add(strKey, func);
		}
	}
	return func;
}

3.实现通用窗口函数

public class LuaWindow : WindowBase
{
    //窗口包含的基本函数
	protected LuaFunction luaFunc_Awake = null;
	protected LuaFunction luaFunc_Start = null;
	protected LuaFunction luaFunc_Update = null;

	public override void Awake()
	{
		if(luaFunc_Awake == null)
		{
			base.Awake();
		}
		else
		{
			luaFunc_Awake.Action<LuaWindow>(this);
		}
	}
	
	public void Base_Awake()
	{
		base.Awake();
	}
}

完整的LuaWindow实现:

public class LuaWindow : WindowBase
{
    //窗口包含的基本函数
	protected LuaFunction luaFunc_Awake = null;
	protected LuaFunction luaFunc_Start = null;
	protected LuaFunction luaFunc_Update = null;
	
	//加载过的窗口
	protected static Dictionary<string, int> mLuaWindowFileDic = new Dictionary<string, int>();
	
	//加载过的函数
	protected static Dictionary<string, LuaFunction> mLuaFunctionDic = new Dictionary<string, LuaFunction>();
	
	public static bool LoadLuaScript(string windowName)
	{
		if(!mLuaWindowFileDic.ContainsKey(windowName))
		{
			if(!LoadXLuaFile("..."+".byte")) //读入xlua文件
				return false;
			mLuaWindowFileDic.Add(windowName, 1);
		}
		return true;
	}
	
	public static LoadXLuaFile(string LuaPath)
	{
		string luaScript = ReadFile(LuaPath); //这里省略把lua代码读入内存的实现
		if(!string.IsNullOrEmpty(luaScript))
		{
			LuaEnv.DoString(luaScript, LuaPath); //Lua虚拟机执行代码
			return true;
		}
		return false;
	}
	
	public void InitLuaFunctions(string windowName)
	{
		object obj = XLuaEnv.Global.Get<object>(windowName);
		LuaTable table = obj as LuaTable;

		luaFunc_Awake = GetLuaFunctionFromTable("Awake", windowName, table);
		luaFunc_Start = GetLuaFunctionFromTable("Start", windowName, table);
		luaFunc_Update = GetLuaFunctionFromTable("Update", windowName, table);
	}
	
	public static LuaFunction GetLuaFunctionFromTable(string functionName, string windowName, LuaTable table)
	{
		LuaFunction func = null;
		string strKey = tableName + table.ToString() + "." + functionName;
		if(!mLuaFunctionDic.TryGetValue(strKey, out func))
		{
			func = table.Get<LuaFunction>(functionName);
			if(func != null)
			{
				mLuaFunctionDic.Add(strKey, func);
			}
		}
		return func;
	}
	
	public override void Awake()
	{
		if(luaFunc_Awake == null)
		{
			base.Awake();
		}
		else
		{
			luaFunc_Awake.Action<LuaWindow>(this);
		}
	}
	
	public void Base_Awake()
	{
		base.Awake();
	}
}

二、Lua新增UI窗口

1.新建一个文件,比如WindowTest.bytes并写入Lua代码

//一个窗口是一个名为窗口名WindowText的table
WindowTest = {}  

//UI缓存变量
local m_Text; 
local m_Transform;

//窗口基类已有函数
WindowTest.Awake = function(self)
	m_Transform = self.transfom:FindChild("XXX");
	m_Text = self.transfom:FindChild("XXX"):GetComponent(typeof(CS.UnityEngine.UI.Text));
	//..
	self:Base_Awake();
end

WindowTest.Update = function(self)
	//..
	self:Base_Update();
end

//新增其他函数
TestNewFunction = function(self)
	//..
end

2.与其他C#类及函数的交互参考patchfile实现

3.调试方法参考patchfile热更调试,放在同一路径下(可自定义专用的window文件夹路径)

游戏开发】