标签:
ulua插件下载地址 www.ulua.org,下面要说的是ulua的开发框架。
首先是 LuaLoader 类,它负责把一个 lua 的 table 加载起来,使此 lua 的 table 像一个 unity 的 component 一样挂在游戏对象上,代码如下:
using LuaInterface;
using System;
using UnityEngine;
public class LuaLoader : MonoBehaviour
{
public string Name;
LuaTable m_table;
LuaFunction m_updateFunc;
LuaFunction m_fixedUpdateFunc;
void Awake()
{
if (string.IsNullOrEmpty(Name))
throw new ArgumentException("Name");
m_table = LuaHelper.GetLuaTable(Name);
if (m_table == null)
throw new ArgumentNullException("No table in " + Name);
// Init lua
m_table["transform"] = transform;
m_table["gameObject"] = gameObject;
// Awake
CallMethod("Awake");
//
m_updateFunc = GetMethod("Update");
m_fixedUpdateFunc = GetMethod("FixedUpdate");
}
void Start()
{
CallMethod("Start");
}
void Update()
{
if (m_updateFunc != null)
m_updateFunc.Call(Time.deltaTime);
}
void FixedUpdate()
{
if (m_fixedUpdateFunc != null)
m_fixedUpdateFunc.Call();
}
void OnEnable()
{
CallMethod("OnEnable");
}
void OnDisable()
{
CallMethod("OnDisable");
}
void OnDestroy()
{
CallMethod("OnDestroy");
// 释放内存
m_table["transform"] = null;
m_table["gameObject"] = null;
m_table.Release();
m_table = null;
if (m_updateFunc != null)
m_updateFunc.Release();
if (m_fixedUpdateFunc != null)
m_fixedUpdateFunc.Release();
LuaScriptMgr.Instance.LuaGC();
}
LuaFunction GetMethod(string methodName)
{
return m_table[methodName] as LuaFunction;
}
void CallMethod(string name)
{
var func = GetMethod(name);
if (func != null)
{
func.Call();
func.Release(); // 释放内存
}
}
public LuaTable Table
{
get { return m_table; }
}
}
其次是 lua 与 c# 的交互,提供了两个帮助类,一个是 LuaHelper ,与游戏逻辑无关的方法封装在里面;另外一个是 LuaUtils, lua 中要访问 c# 代码的方法(与游戏逻辑有关的)都封装在里面。
LuaHelper 关键的几个方法代码如下:
using LuaInterface;
using Resource;
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
public static class LuaHelper
{
#region GetLuaComponent
public static LuaTable GetLuaComponent(Transform transform, string type)
{
var loaders = transform.GetComponents<LuaLoader>();
var rightLoader = loaders.FirstOrDefault(lt => lt.Table != null && lt.Table.name == type);
return rightLoader != null ? rightLoader.Table : null;
}
public static LuaTable GetLuaComponent(GameObject gameObject, string type)
{
return GetLuaComponent(gameObject.transform, type);
}
#endregion
/// <summary>
/// 从ab包中加载table,供lua使用
/// </summary>
/// <param name="name">table名</param>
public static void LoadLuaTable(string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException("name");
LuaTable table = LuaScriptMgr.Instance.GetLuaTable(name);
if (table == null)
{
using (var loadLua = new LoadLuaHandler(name))
LuaScriptMgr.Instance.DoString(loadLua.Text);
}
}
public static LuaTable GetLuaTable(string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException("name");
LuaTable table = LuaScriptMgr.Instance.GetLuaTable(name);
if (table == null)
{
using (var loadLua = new LoadLuaHandler(name))
LuaScriptMgr.Instance.DoString(loadLua.Text);
table = LuaScriptMgr.Instance.GetLuaTable(name);
}
return table;
}
public static LuaFunction GetLuaFunction(string className, string funcName)
{
if (string.IsNullOrEmpty(className))
throw new ArgumentException(className);
if (string.IsNullOrEmpty(funcName))
throw new ArgumentException(funcName);
LuaTable table = GetLuaTable(className);
return table[funcName] as LuaFunction;
}
public static object[] CallFunction(string className, string funcName, params object[] args)
{
LuaFunction func = GetLuaFunction(className, funcName);
if (func == null)
throw new ArgumentNullException(string.Format("Cann‘t find lua function: {0}.{1}", className, funcName));
var returnArgs = args == null ? func.Call() : func.Call(args);
func.Release();
return returnArgs;
}
}
另外,关于通过 lua 代码给c#打补丁的功能,是在 UIPanel OnEnable 的第一帧检测补丁和打补丁的,c#代码如下:
using LuaInterface;
using System;
using System.Collections.Generic;
using UnityEngine;
public class LuaPatchManager : IDisposable
{
List<Patch> m_patches;
#region Singleton
static LuaPatchManager s_instance;
public static LuaPatchManager Instance
{
get { return s_instance; }
}
#endregion
#region Patch
class Patch : IDisposable
{
LuaFunction m_validate;
LuaFunction m_correct;
public Patch(LuaFunction validate, LuaFunction correct)
{
if (validate == null)
throw new ArgumentNullException("validate");
if (correct == null)
throw new ArgumentNullException("correct");
m_validate = validate;
m_correct = correct;
}
public bool Validate(UIPanel uiPanel)
{
var objs = m_validate.Call(uiPanel);
return (bool)objs[0];
}
public void Correct(UIPanel uiPanel)
{
m_correct.Call(uiPanel);
}
#region IDisposable
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
void Dispose(bool disposing)
{
if (disposing)
{
m_validate.Release();
m_validate = null;
m_correct.Release();
m_correct = null;
}
}
~Patch()
{
Dispose(false);
}
#endregion
}
#endregion
private LuaPatchManager(LuaTable listTable)
{
if (listTable == null || listTable.Values.Count <= 0)
throw new ArgumentException("listTable == null || listTable.Values.Count <= 0");
m_patches = new List<Patch>();
foreach (string name in listTable.Values)
{
var patch = LuaHelper.GetLuaTable(name);
if (patch != null)
{
var validateFunc = patch["Validate"] as LuaFunction;
var correctFunc = patch["Correct"] as LuaFunction;
if (validateFunc != null && correctFunc != null)
m_patches.Add(new Patch(validateFunc, correctFunc));
patch.Release();
}
}
listTable.Release();
LuaScriptMgr.Instance.LuaGC();
}
public static void Load()
{
LuaTable listTable = null;
string targetFileName = "LuaPatchList";
try
{
listTable = LuaHelper.GetLuaTable(targetFileName);
}
catch
{
Debug.LogWarning("No file: " + targetFileName);
}
if (listTable != null)
{
if (listTable.Values.Count > 0)
s_instance = new LuaPatchManager(listTable);
listTable.Release();
}
}
public void DoPatch(UIPanel uiPanel)
{
if (uiPanel == null)
throw new ArgumentNullException("uiPanel");
for (int i = 0; i < m_patches.Count; i++)
{
Patch p = m_patches[i];
if (p.Validate(uiPanel))
{
p.Correct(uiPanel);
break;
}
}
}
#region IDisposable
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
void Dispose(bool disposing)
{
if (disposing)
{
for (int i = 0; i < m_patches.Count; i++)
m_patches[i].Dispose();
m_patches.Clear();
m_patches = null;
}
}
~LuaPatchManager()
{
Dispose(false);
}
#endregion
}
lua代码如下:
LuaPatchList=
{
};
// 一个补丁例子如下:
MainInfoControllerPatch={};
local function ClickTest()
TipsShowController.Show("Who are you?");
end
-- 验证此uiPanel是否是希望打补丁的uiPanel --
function MainInfoControllerPatch.Validate(uiPanel)
return uiPanel.transform.parent~=nil and uiPanel.transform.parent.name=="MainInfoController(Clone)";
end
-- 纠正此uiPanel上的展示内容,执行方法等 --
function MainInfoControllerPatch.Correct(uiPanel)
local titleLabel=uiPanel.transform:Find("LabelName"):GetComponent("UILabel");
titleLabel.text="TianJie";
local mustBuyButton=uiPanel.transform:Find("ButtonFashion"):GetComponent("UIButton");
mustBuyButton.onClick:Clear();
EventDelegate.Add(mustBuyButton.onClick,DelegateFactory.EventDelegate_Callback(ClickTest));
end
标签:
原文地址:http://www.cnblogs.com/jietian331/p/4955282.html