uLua+SimpleFramework常见问题的解答及学习笔记


请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com

本文所使用的uLua+SimpleFramework版本,没有特别指明的情况下,是使用了0.4.0.2 for NGUI版本。

  1. ulua的标准库函数print在ulua里面是否有for Unity3D的封装?
  2. uLua是怎样把Unity3D的类导出给lua语言去调用的?大致流程是怎样?
  3. 用反射机制导出使用C#还是太慢了,有更快的方案吗?
  4. 如何把自定义的C#类导出给lua语言调用
  5. 打开v1.23版本的AccessingLuaVariables_02.unity,执行报错,咋整?
  6. SimpleFramework提供的资源热更新的机制的流程是咋回事?
  7. SimpleFramework的界面创建流程好像很复杂,有没有能快速让人理解的流程图

Q: ulua的标准库函数print在ulua里面是否有for Unity3D的封装

A: 有,在Assets\uLua\Core\LuaStatic.cs文件中,有个如下声明的方法:

[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
public static int print(IntPtr L)
{
    // 此处代码从略...
    Debug.Log("LUA: " + s);
    return 0;
}

此方法就是对应封装了实现了print的重新实现。当你使用的uLua提供的LuaState装载一段lua代码之后,print函数就会将这个打印输出重定向到Unity3D的控制台中。


Q: uLua是怎样把Unity3D的类导出给lua语言去调用的?大致流程是怎样?

A: 答案之一就是在LuaInterface.LuaState类中。每实例化一个LuaState类时,在该类的构造函数中,便会做一次初始化uLua环境的操作,LuaState类定义在LuaStatic.cs代码中,点击定位到LuaState类中可见到其构造方法

可以看到,LuaState在构造之始,在lua堆栈中注册了一个名字为luanet的全局变量。
LuaState类有一个内部成员变量translator,它是ObjectTranslator类型的。该对象随着LuaState对象的创建而创建。这个类主要是把用C#实现的诸如“装载程序集”,“用反射机制导入C#的类型到lua”等等的函数,注册到本lua state里面去,并且提供了能在lua语言中调用的函数,如“装载程序集”对应的lua函数名为load_assembly,“用反射机制导入C#的类型到lua”对应的lua函数名为import_type等等。

然后,执行一段lua代码,即LuaStatic.init_luanet字符串的内容,完全初始化好lua环境中的luanet变量。最后则是把打印堆栈的方法trackback注册到lua state中。

打开Assets\uLua\Examples\02_CreateGameObject目录,装载入场景文件CreateGameObject_01.unity。观察挂载到场景中名字为“GameObject”的game object上的脚本,你便能发现如何反射机制去把Unity3D的类导出给lua语言去调用的。


Q: 用反射机制导出使用C#还是太慢了,有更快的方案吗?

A: 有,uLua提供了去反射导出使用LuaState的机制。主要是通过LuaScriptMgr类和LuaBinder两个类完成,首先看LuaScriptMgr类的构造方法。此类定义在LuaScriptMgr.cs文件,点击可看到:

  1. 第1步,调用Utils.CheckEnvironment方法检查“导出把C#类导出到lua的用C#编写的‘包装’文件的目录”;以及资源路径的配置。在全局配置类有一个AppConst.uLuaPath变量,把C#类导出到lua的用C#编写的“包装文件”将会放在“AppConst.uLuaPath/Source/LuaWrap”目录下。
  2. 第2步,把lua脚本文件的装载器,即LuaScriptMgr.loader成员方法传递给LuaStatic.Loader成员。uLua将会使用此装载器去装载lua脚本代码。
  3. 第3步,创建出一个LuaState对象
  4. 第4步,把一些第三方lua库,如json,protobuf等等,装载进创建出来的lua state。
  5. 第5步,就是关键之处,即调用本类的成员方法Bind。Bind方法主要做了两个操作,第1步就是调用DelegateFactory.Register方法,把一些委托操作相关的代码装载进本lua state。第2步就是转调LuaBinder类的Bind方法。Bind方法就是把通过“点击uLua的工具菜单【Gen Lua Wrap Files】生成的,以去反射方式包装C#导出给lua用的C#类的C#源文件”,依次载入到本lua state中。

Q: 如何把自定义的C#类导出给lua语言调用?

A: 打开Assets\uLua\Editor\BindLua.cs文件。找到BindType[]类型的静态变量binds,仿照代码中的写法,依样画葫芦,便可将你定义的C#类导出给lua使用。


Q: 打开v1.23版本的AccessingLuaVariables_02.unity,执行报错,咋整?
A: 这是开发人员的一个疏忽,打开Assets\uLua\Examples\03_AccessingLuaVariables\AccessingLuaVariables02.cs,修改脚本代码,如下图所示:

如图所示,加上UnityEngine即可。


Q: SimpleFramework提供的资源热更新的机制的流程是咋回事?

A:这里,代码有注解分析了


Q: SimpleFramework的界面创建流程好像很复杂,有没有能快速让人理解的流程图?

A:这里,有流程图

返回首页