首页 技术 正文
技术 2022年11月10日
0 收藏 392 点赞 3,037 浏览 7541 个字

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; /// <summary>
/// 通过 Name 名,加载对应的 lua table,并将之“挂”在游戏对象上。
/// </summary>
/// <returns>是否加载成功</returns>
public bool Load()
{
if (string.IsNullOrEmpty(Name))
return false; m_table = LuaHelper.GetLuaTable(Name);
if (m_table == null)
return false; // Init lua
m_table["transform"] = transform;
m_table["gameObject"] = gameObject; //
m_updateFunc = GetMethod("Update");
m_fixedUpdateFunc = GetMethod("FixedUpdate"); return true;
} void Awake()
{
if (Load())
CallMethod("Awake");
else
{
if (!string.IsNullOrEmpty(Name)) // 如果 Name 为空,可能是 Add component
throw new ArgumentNullException("Load lua table failed, no table in " + Name);
}
} void Start()
{
if (m_table == null) // 此处应为 Add component 的情况
{
if (string.IsNullOrEmpty(Name))
throw new ArgumentException("string.IsNullOrEmpty(Name)"); if (!Load())
throw new ArgumentNullException("Load lua table failed, no table in " + Name);
} 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 != null ? m_table[methodName] as LuaFunction : null;
} void CallMethod(string name)
{
var func = GetMethod(name); if (func != null)
{
func.Call();
func.Release(); // 释放内存
}
} public LuaTable Table
{
get { return m_table; }
}
}

LuaLoader

  

其次是 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;
using UObject = UnityEngine.Object;public static class LuaHelper
{
#region Lua public static LuaTable GetLuaComponent(Transform transform)
{
if (transform == null)
throw new ArgumentNullException("transform"); var loaders = transform.GetComponents<LuaLoader>();
var rightLoader = loaders.FirstOrDefault(lt => lt.Table != null); return rightLoader != null ? rightLoader.Table : null;
} public static LuaTable GetLuaComponent(GameObject gameObject)
{
return GetLuaComponent(gameObject.transform);
} public static LuaTable GetLuaComponent(Transform transform, string type)
{
if (transform == null)
throw new ArgumentNullException("transform");
if (string.IsNullOrEmpty(type))
throw new ArgumentException("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);
} public static LuaTable AddLuaComponent(GameObject gameObject, string type)
{
var loader = gameObject.AddComponent<LuaLoader>();
loader.Name = type;
loader.Load();
return loader.Table;
} /// <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;
} #endregion
}

LuaHelper

另外,关于通过 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[];
} 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 <= )
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 > )
s_instance = new LuaPatchManager(listTable); listTable.Release();
}
} public void DoPatch(UIPanel uiPanel)
{
if (uiPanel == null)
throw new ArgumentNullException("uiPanel"); for (int i = ; 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 = ; i < m_patches.Count; i++)
m_patches[i].Dispose(); m_patches.Clear();
m_patches = null;
}
} ~LuaPatchManager()
{
Dispose(false);
} #endregion
}

LuaPatchManager

lua代码如下:

LuaPatchList=
{
"MainInfoControllerPatch",
};

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

Patch

转载请注明出处:http://www.cnblogs.com/jietian331/p/4955282.html

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,495
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,297