关于Lua在Unity 中的使用

 

对于手机游戏,如果可以在线更新以实现bug修复、新功能添加等等,其好处自不必多说。

通过C#的反射机制,也可以实现某种程度上的脚本级更新,具体可以参考

http://docs.unity3d.com/Documentation/Manual/scriptsinassetbundles.html

但其中也明确指出了在iOS上不支持反射。所以很自然的,想到使用Lua、Python等脚本语言来解决需求。撇开Python不讲(感兴趣的可以搜索UniPython),来看Lua。

因为Lua本身使用C语言实现,具有良好的跨平台特性,但我们使用C#来作为主要开发语言,要实现与Lua的混合开发,最好是有一个C#版的Lua。万能的google的帮我找到了UniLua(https://github.com/xebecnan/UniLua),特别感谢其作者xebecnan。PS:xebecnan貌似是云风(云风BLOG)团队的,当看到UniLua是国人实现的,且云风的Unity3d项目也在使用时,便立刻决定试一下:)

在现在这个项目之前,几乎没有任何的Lua使用经验,完全是从开始。国内关于Lua的书籍和资料貌似都很少,书的话官方的《Lua程序设计》必读,《Lua游戏开发实践指南》也可以快速翻一翻。个人觉得有用的资源还有:

官方的参考手册-居家旅行必备:http://www.lua.org/manual/5.2/

简明教程 http://coolshell.cn/articles/10739.html

Lua与C++的混合编程入门 http://blog.csdn.net/jason3/article/details/5653487

关于如何在Unity3d中使用UniLua,wiki上面已经讲的非常清晰了。其中也讲到了如何在Lua中调用C#,不过仅给出了调用静态成员函数的示例,而我仅在此记录一下如何在Lua调用C#中的非静态成员函数。

现有C#中的People类如下

 1 public class People
2 {
3 public People(int age)
4 {
5 Age = age;
6 }
7
8 public int Age
9 {
10 get;
11 set;
12 }
13
14 public bool IsYounger(People other)
15 {
16 return (Age < other.Age);
17 }
18 }

如何在lua中调用People的成员函数IsYounger?

1. 如何访问C#的对象:使用 light userdata,即使用UniLua提供的 PushLightUserData() 和 ToUserData()

2. 如何访问C#的成员函数:主要是利用PushCSharpFunction() 接口,但过程略麻烦一些。

  2.1 将C#类中的成员函数都封装为静态成员函数(后附示例代码)

  2.2 将上面的静态成员函数设置为lua的全局变量,以在lua中调用

示例代码:

 1 public class PeopleLuaWrapper
2 {
3 const string CLASS_NAME = "People";
4
5 public static void RegisterCSharpMethod(ILuaState lua)
6 {
7 lua.NewTable();
8 int method_table = lua.GetTop();
9
10 lua.PushString("IsYounger");
11 lua.PushCSharpFunction(IsYounger);
12 lua.SetTable(method_table); //将函数设置为table的一个元素
13
14 lua.SetGlobal(CLASS_NAME); //设置名为CLASS_NAME的全局表
15 }
16
17 //! 将原成员函数重新封装为静态成员函数
18 private static int IsYounger(ILuaState lua)
19 {
20 People invoker = (People)lua.ToUserData(1); //获取成员函数的调用者
21 People other = (People)lua.ToUserData(2); //获取成员函数的参数
22 lua.Pop(2);
23
24 bool is_younger = invoker.IsYounger(other);
25 lua.PushBoolean(is_younger); //将函数结果压栈
26
27 return 1;
28 }
29 }

lua中调用C#成员函数:

 1 local function Lua_IsYounger(pa, pb)
2 is_younger = People.IsYounger(pa, pb)
3 return is_younger
4 end
5
6
7 return
8 {
9 Lua_IsYounger = Lua_IsYounger,
10 }

在C#中调用lua代码:

 1         ILuaState lua = LuaAPI.NewState();
2 lua.L_OpenLibs();
3
4 PeopleLuaWrapper.RegisterCSharpMethod(lua);
5
6 People pa = new People(12);
7 People pb = new People(123);
8
9 var status = lua.L_DoFile("People.lua");
10
11 lua.GetField(-1, "Lua_IsYounger");
12 lua.PushLightUserData(pa);
13 lua.PushLightUserData(pb);
14 lua.Call(2, 1);
15
16 bool is_younger = lua.ToBoolean(-1);

示例代码毫无实用意义,但应该足以说明如何实现C#与Lua之间的互相调用。

本人纯粹Lua新手,这种做法也不知是否合理,或者有更简便的实现方法,请指教。

Lua------------------unity关于lua的使用的更多相关文章

  1. Unity进阶----Lua语言知识点(2018/11/08)

    国内开发: 敏捷开发: 集中精力加班堆出来第一个版本 基本没啥大的bug 国外开发: 1).需求分析: 2).讨论 3).分模块 4).框架 5).画UML图(类图class function)(e- ...

  2. 用好lua+unity,让性能飞起来——关于《Unity项目常见Lua解决方案性能比较》的一些补充

    <Unity项目常见Lua解决方案性能比较>,这篇文章对比了现在主流几个lua+unity的方案 http://blog.uwa4d.com/archives/lua_perf.html ...

  3. 用好lua+unity,让性能飞起来——lua与c#交互篇

    前言 在看了uwa之前发布的<Unity项目常见Lua解决方案性能比较>,决定动手写一篇关于lua+unity方案的性能优化文. 整合lua是目前最强大的unity热更新方案,毕竟这是唯一 ...

  4. (转 )Unity对Lua的编辑器拓展

    转 http://blog.csdn.net/ZhangDi2017/article/details/61203505 当前版本的Unity(截至Unity5.5.x)中TextAsset类不支持后缀 ...

  5. tolua#是Unity静态绑定lua的一个解决方案

    tolua#代码简要分析 2017-04-16 23:02 by 风恋残雪, 98 阅读, 1 评论, 收藏, 编辑 简介 tolua#是Unity静态绑定lua的一个解决方案,它通过C#提供的反射信 ...

  6. Lua 架构 The Lua Architecture

    转载自:http://magicpanda.net/2010/10/lua%E6%9E%B6%E6%9E%84%E6%96%87%E6%A1%A3/ Lua架构文档(翻译) 十 102010 前段时间 ...

  7. vJine 第三波 之 Lua 来袭 vJine.Lua

    vJine.Lua vJine.Lua是Lua语言的C#封装库,可实现通过C#直接运行Lua脚本并与Lua脚本交互的功能. 1. 授权: MPL2.0 相关资源: nuget:(https://www ...

  8. VC和VS调用Lua设置以及Lua C API使用。

    通过c++调用lua 脚本,    环境VC++6.0    lua  sdk 5.1.4 在调用前先认识几个函数.1.调用lua_open()将创建一个指向Lua解释器的指针.2. luaL_ope ...

  9. lua调用不同lua文件中的函数

    a.lua和b.lua在同一个目录下 a.lua调用b.lua中的test方法,注意b中test的写法 _M 和 a中调用方法: b.lua local _M = {}function _M.test ...

  10. 通过lua栈了解lua与c的交互

    lua是如何执行的 其中分析.执行部分都是c语言实现的. lua与c的关系 lua的虚拟机是用c语言实现的,换句话说一段lua指令最终在执行时都是当作c语言来执行的,lua的global表,函数调用栈 ...

随机推荐

  1. C++ STL set和multiset的使用

    C++ STL set和multiset的使用 std::set<int> s;那个s这个对象里面存贮的元素是从小到大排序的,(因为用std::less作为比较工具.) 1,set的含义是 ...

  2. 在vue-cli生成的项目中使用karma+chrome进行单元测试

    用vue-cli生成项目时,如果选择了单元测试,那么会采用karma+mocha作为单元测试框架,默认使用的浏览器是PhantomJs. Karma 是一个基于Node.js的JavaScript测试 ...

  3. 使用FastJson从json串中根据key获取value

    import com.alibaba.fastjson.JSONObject; /** * Created by SYJ on 2017/9/13. */ public class MainTest ...

  4. idea Error:(1, 10) java: 需要class, interface或enum, 未结束的字符串文字,Error:(55, 136) java: 非法字符: \65533

    1.未结束的字符串文字,Error:(55, 136) java: 非法字符: \65533  这些乱七吧八遭的错误如果很多的话 , 尝试 重新修改下生成目录 修改下语言等级 上述方法都不行 ,还报错 ...

  5. mysql行转列转换

    http://blog.csdn.net/sinat_27406925/article/details/77507478 mysql 行列转换 ,在项目中应用的极其频繁,尤其是一些金融项目里的报表.其 ...

  6. git pull出现There is no tracking information for the current branch

    使用git pull 或者 git push 的时候报错 gitThere is no tracking information for the current branch. Please spec ...

  7. http连接优化与浏览器允许的并发请求资源数相关资料(整理转载)

    网页性能优化相关资料: https://developer.yahoo.com/performance/rules.html#page-nav 前端技术的逐渐成熟,还衍生了domain hash, c ...

  8. [mqtt]mqtt嵌入式移植

    github eclipse paho source code: https://github.com/mqtt/mqtt.github.io/wiki/libraries STM32 mqtt移植: ...

  9. strace用法说明

    strace命令详解strace 命令是一种强大的工具,它能够显示所有由用户空间程序发出的系统调用. strace 显示这些调用的参数并返回符号形式的值.strace 从内核接收信息,而且不需要以任何 ...

  10. RavenDb学习(七) 异步工作以及维度查询

    .异步执行 var entity = new Company {Name = "Async Company #2", Id = "companies/2"}; ...