您的位置:首页 > 编程语言 > Lua

uLua学习笔

2016-03-15 14:03 543 查看
uLua下载:http://www.ulua.org/

VS2012/2013的用于编写Lua的插件:https://babelua.codeplex.com/http://unknownworlds.com/decoda/

在下载了uLua_vX.XX.zip后解压得到一个XXX.unitypackage文件,将该文件导入到我们的工程中即可使用uLua了。

我们先来一个最简单的示例:

1 using UnityEngine;
2 using System.Collections;
3 using LuaInterface;
4
5 public class LuaTest : MonoBehaviour
6 {
7     void Start ()
8     {
9         LuaState luaState = new LuaState();
10         luaState.DoString("print('hello world 世界')");
11     }
12 }


将该脚本绑定到场景中的一个GameObject之上就可以看到效果了。

下面我们看一个加载外部lua文件的例子:

我们新建一个Resources目录,在目录里创建一个名为Test.lua.txt的文件,输入lua代码:

1 print("This is a script from a file 世界")


保存为UTF-8格式,注意Unity的TextAsset不支持lua的后缀名,所以后缀名要修改为txt。

修改上面的示例为下面的代码即可:

1 using UnityEngine;
2 using System.Collections;
3 using LuaInterface;
4
5 public class LuaLoadFileTest : MonoBehaviour
6 {
7     void Start ()
8     {
9         TextAsset luaString = Resources.Load<TextAsset>("Test.lua");
10
11         LuaState luaState = new LuaState();
12         luaState.DoString(luaString.text);
13     }
14 }


注意Load的文件是不带后缀名的。

下面的例子使用uLua创建一个GameObject:

1 using UnityEngine;
2 using System.Collections;
3 using LuaInterface;
4
5 public class LuaTest : MonoBehaviour
6 {
7     private string lua = @"
8             --加载模块
9             luanet.load_assembly('UnityEngine')
10             luanet.load_assembly('Assembly-CSharp')
11
12             --导入 Unity3D 的类
13             Util = luanet.import_type('Util')
14             GameObject = luanet.import_type('UnityEngine.GameObject')
15
16             --创建一个新的 GameObject 对象
17             local newGameObj = GameObject('NewObj')
18             --添加粒子组件
19             Util.AddComponent(newGameObj, 'UnityEngine', 'ParticleSystem')
20         ";
21
22     void Start ()
23     {
24         LuaState luaState = new LuaState();
25         LuaScriptMgr._translator = luaState.GetTranslator();
26         luaState.DoString(lua);
27     }
28 }


下面的例子是设置和获取Lua中的变量:

1 using UnityEngine;
2 using System.Collections;
3 using LuaInterface;
4
5 public class LuaTest : MonoBehaviour
6 {
7     private string lua = @"
8             --加载模块
9             luanet.load_assembly('UnityEngine')
10             luanet.load_assembly('Assembly-CSharp')
11
12             --导入 Unity3D 的类
13             Util = luanet.import_type('Util')
14             GameObject = luanet.import_type('UnityEngine.GameObject')
15
16             --创建表
17             particles = {}
18
19             --循环
20             for i = 1, Objs2Spawn, 1 do
21                 --创建 GameObject 对象
22                 local newGameObj = GameObject('NewObj' .. tostring(i))
23                 --添加组件
24                 local ps = Util.AddComponent(newGameObj, 'UnityEngine', 'ParticleSystem')
25                 --暂停粒子播放
26                 ps:Stop()
27
28                 --加入表
29                 table.insert(particles, ps)
30             end
31
32             --定义一个数据
33             var2read = 42
34         ";
35
36     void Start ()
37     {
38         LuaState luaState = new LuaState();
39         LuaScriptMgr._translator = luaState.GetTranslator();
40
41         //赋值 Lua 中的数据
42         luaState["Objs2Spawn"] = 5;
43
44         luaState.DoString(lua);
45
46         //读取 Lua 中的数据
47         print("Read from lua: " + luaState["var2read"].ToString());
48
49         //获取 LuaTable 对象
50         LuaTable particles = (LuaTable)luaState["particles"];
51
52         //遍历播放粒子
53         foreach(ParticleSystem ps in particles.Values)
54         {
55             ps.Play();
56         }
57     }
58 }


下面看看Unity如何调用uLua中的函数:

1 using UnityEngine;
2 using System.Collections;
3 using LuaInterface;
4
5 public class LuaTest : MonoBehaviour
6 {
7     private string lua = @"
8             --定义一个函数
9             function luaFunc(message)
10                 print(message)
11                 return 42
12             end
13         ";
14
15     void Start ()
16     {
17         LuaState luaState = new LuaState();
18         LuaScriptMgr._translator = luaState.GetTranslator();
19
20         //运行脚本确保函数已经创建
21         luaState.DoString(lua);
22
23         //获取函数
24         LuaFunction func = luaState.GetFunction("luaFunc");
25
26         //调用函数
27         object[] result = func.Call("I called a lua function!");
28
29         //获取结果
30         print(result[0]);
31     }
32 }


下面我们看看lua和U3D之间是如何相互传递数组:

1 using UnityEngine;
2 using System.Collections;
3 using LuaInterface;
4 using System;
5
6 public class LuaTest : MonoBehaviour
7 {
8     private string lua = @"
9         --定义一个函数
10         function luaFunc(objs, len)
11             for i = 0, len - 1 do
12                 print(objs[i])
13             end
14             --返回一个列表
15             local table1 = {'111', '222', '333'}
16             return table1
17         end
18     ";
19
20     string[] objs = { "aaa", "bbb", "ccc" };
21
22     void Start ()
23     {
24         LuaScriptMgr luaMgr = new LuaScriptMgr();
25         LuaState luaState = luaMgr.lua;
26         luaState.DoString(lua);
27
28         //调用lua的函数获取返回值
29         LuaFunction f = luaState.GetFunction("luaFunc");
30         object[] rs = f.Call(objs, objs.Length);
31
32         //输出lua的返回值
33         LuaTable table = rs[0] as LuaTable;
34         foreach (DictionaryEntry de in table)
35         {
36             Debug.Log(de.Value);
37         }
38     }
39 }


接下来我们看看Lua里的协程:

1 using UnityEngine;
2 using System.Collections;
3 using LuaInterface;
4
5 public class LuaCoroutines : MonoBehaviour {
6
7     private string script = @"
8             --导入程序集
9             luanet.load_assembly('UnityEngine')
10             --导入类型
11             local Time = luanet.import_type('UnityEngine.Time')
12
13             --使运行暂停指定的时间, 每帧调用
14             function waitSeconds(t)
15                 --获得结束时间
16                 local timeStamp = Time.time + t
17                 --时间没到就 yield 中断
18                 while Time.time < timeStamp do
19                     coroutine.yield()
20                 end
21             end
22
23             --外部调用的方法
24             function myFunc()
25                 print('Coroutine started')
26                 local i = 0
27                 for i = 0, 10, 1 do
28                     print(i)
29                     waitSeconds(1)
30                 end
31                 print('Coroutine ended')
32             end
33         ";
34
35     private LuaThread co = null;
36
37     void Start () {
38         LuaState l = new LuaState();
39         LuaScriptMgr._translator = l.GetTranslator();
40
41         //创建函数
42         l.DoString(script);
43
44         //获取函数
45         LuaFunction f = l.GetFunction("myFunc");
46
47         //创建协同程序
48         co = new LuaThread(l, f);
49
50         //启动协同程序
51         co.Start();
52     }
53
54     void Update () {
55         if( !co.IsDead() )
56         {
57             //协同程序需要每帧进行调用
58             co.Resume();
59         }
60         else
61         {
62             print("Coroutine has exited.");
63
64             //清除协同程序
65             co = null;
66         }
67     }
68 }


uLua&SimpleFramework入门视频教程网盘地址

视频教程地址 http://pan.baidu.com/s/1gd8fG4N 游戏框架地址 https://github.com/jarjin 游戏案例地址 http://www.ulua.org/showcase.htmlulua群里的一些资料,转过来方面查看 ulua学习顺序。请根据自身了解的知识入座。 初级:SimpleFramework框架 中级:ulua插件、cstolua 高级:底层库编译。 框架的角色定位分为2种, 第一种,对于有框架的大厂,它就是个使用ulua+cstolua的一个比较完整的demo。 第二种,对于没有框架的同学,可以自己基于它修改、扩展。 wrap就是c#类提供给lua用的接口文件attempt to index global 'System' (a nil) 刚下载后,需要做两步操作 (1)Lua/Gen lua wrap files 生成wrap (2)Game/Build Bundle Resource(NGUI版) 生成资源 Game/Build AssetBundles (UGUI版) 生成资源关于unknow lua error lua文件编码问题处理 如果lua文件中保护中文注释等信息,文件保存为utf8-bom,如果怕麻烦干脆把中文去掉,然后保存成utf8即可解决问题。unprotected error in call to Lua API LuaInterface.LuaException: unprotected error in call to Lua API (Loader file failed: game) 检查Lua变量是不是少了local关键字.或者关掉变量检查strict.lua,在Golbal.lua中注释掉require "strict"mac下编译工程找不到lua.h办法 删除ulua/Source目录,retry~ulua底层库&Mingw编译工具下载,百度网盘 下载地址:http://pan.baidu.com/s/1gd1Wyx9 ulua已经全部开源,你们可以定制自己需要的库,mac、ios是luavm,需要xcode6.0以上,安卓需要ndk 8,windows下编译工具mingw32/64。我是放在D盘根目录: 32位:D:\MinGW\x86\msys\1.0\msys.bat 64位:D:\MinGW\x64\msys\1.0\msys.bat 真正的安卓版的编译文件在这个下面:Source\android\jniulua资料位置 NGUI版、UGUI版、WINPHONE版框架地址: http://www.ulua.org/simpleframework.html 最完整的文档注解:群共享里面SimpleFramework_v0.2.7注解 - 完整版_luaopen_pack, referenced from: "错误 "_luaopen_pack", referenced from: "_lua_tocbuffer", referenced from: 去掉LuaDLL.cs中报错函数声明,及其相关报错代码即可.lua关系 ulua -》很早老外基于luainterface做的一个unity版lua绑定 luajit-》一个jit版本的luavm cstolua-》最初基于ulua,现在优化的很棒和ulua关联已不多的一个基于静态导出的lua绑定游戏已经开发到后期,如何接入ulua? (1)活动 (2)计时器(单位秒)驱动lua的update (3)网络管理留给lua能跟服务器交互的接口(现在未必用得到的)。活动这部分变数最大,很多问题上线前是无法预知的,比如上线如果发生数据不理想,或者非常火爆,这些情况无法预知,根据这些情况做活动调整,这些很容易有更新需求。而且未必前期都能想到坐进去。运营策划都是要根据在线运营情况做未知的活动调整。还有一部分我称之为,程序给自己留的后路,如果绝大部分都是c#的话,很有可能产生上线后产生bug,比如:新手引导,在什么地方卡住了等。客户端启动一个计时器,驱动lua的一个onTimer,在里面根据游戏运行情况,动态调整对游戏的控制。还有就是多给自己留一个协议的接口给lua备份用。Unity手游究竟有无必要做代码热更新 Unity热更新的必要性:(开发期)减少手游打包次数,大大缩短开发周期,提升程序调试效率。(运营期)减少大版本更新次数,可以减少用户流失,抱怨,提高留存,付费等。simpleframework 下载运行崩溃办法 因为开发期不知道大家Unity版本,为了减少错误,wrap文件在发布的时候都被clear掉了,所以当大家一开始下载运行的时候,这部分是缺少的,需要单击菜单Lua/Gen Lua Wrap Files。另外资源文件也需要根据自己的版本重新生成。操作步骤:(1)单击菜单Lua/Gen Lua Wrap Files。(2)单击Game/Build Bundle Resource。simpleframework百度网盘下载地址 如果群共享与ulua.org上下载不下来,请到百度网盘备份http://yun.baidu.com/s/1jGzN78q#path=%252FSimpleFrameworkGUI 的Prefab损坏解决办法 把GUI.zip,解压,,替换.GUI下面的摄像机视野改成everything,Tag 改成 GuiCamera,GUI的所在层 改成default. 估计丢失原因是因为我来回切换Unity版本所致。用上面办法解决即可。手动重新生成wrap文件方法 删除Source/LuaWrap/下面的cs文件,Base目录及其下面文件千万别删,然后清除报错代码即可. 然后单击Lua/Gen LuaBinding Files生成新的wrap文件即可U5不推荐使用NGUI的原因 u5的新格式打包,ngui不支持,作者也不准备修复(让我高兴,自己改),老的打包函数又被标记丢弃,怎么看都有被抛弃的可能,再转可能就有很大风险。所以新的项目推荐使用UGUI,框架已经有UGUI+U5新打包版本,地址:http://ulua.org/simpleframework.html 不支持部分:新版assetbundle中的prefab不能有拖拽脚本,NGUI里面哪个组建没有这个atlas拖拽脚本?没人自己愿意修改每个组建的atlas变成GameObject吧???苹果新政禁止开发者加入检查更新功能办法 主要停留在审核期,在服务器设定一个开关,审核期把检查更新功能关闭,审核期过了,再打开即可。修改lua代码调用路径 如果使用Simpleframework框架的话,lua代码文件的位置在Util.cs类的LuaPath函数里面指定。打印不出中文的bug 修改lua.cs, 搜索encoding.default , 改成utf8.object contains non-primitive or xxx object contains non-primitive or non-blittable data的错误,这个是iOS il2cpp运行bug,请参考 http://ulua.org/simpleframework.htmlSimpleFramework_v0.2.0 Patch1 补丁进行修改升级。LuaWrap/xxxWrap.cs does nontain for ‘xx’ Assets/Source/LuaWrap/xxxWrap.cs(218,21): error CS1061: Type `UnityEngine.xxx' does not contain a definition for `xxx' and noextension method `xxx' of type `UnityEngine.xxx' could be found (are you missing a using directive or an assembly reference?) 编译错误解决方案:因为unity不同平台版本api各不相同,因此不是特别统一,遇到此问题直接删除错误代码即可。ulua(安卓+ios),nlua(windows phone) ulua包含两种c模式(luajit版+原生luavm版),加之tolua c#提供了直接访问渠道。所以追求效率的,请选用ulua。但是ulua因为底层使用luajit,而luajit目前不能在WP平台使用,所以如果ulua支持WP平台需要第二种原生luavm的底层库。 nlua包含2种模式(KeraLua c版本)(KopiLua c#版本),它支持全平台,因为c版本底层用的原始的luavm(非luajit)。但是缺少tolua c#的支持,因此效率略低于ulua,但是支持WP平台(其他平台也支持)。DllNotFoundException: ulua解决方案 (1)将plugins目录放到最外面,重启unity。 (2)缺失VC++ 2012 Runtime。 (3)mac运行期,不用选项ios平台。生成真机再选ios。 (4)真机没有打包libulua.so进包导致,或者模拟器也有些设置不对。打包的时候把libulua.so打包进libs\armeabi-v7aLuaStudio 调试卡死 控制面板->用户账户->更改用户账户控制设置面板->始终通知 改为从不通知attempt to index global 'UnityEngine' uaScriptException: [string "define.lua"]:1: attempt to index global 'UnityEngine' (a nil value) 解决:生成wrap文件。EntryPointNotFoundException: 解决方案 EntryPointNotFoundException:这个类型错误不太单一,可选择下面2中方法解决:(方案1)把除了Assets跟ProjectSettings目录之外的都删除掉,重新打开工程。 (方案2)如果在MAC上,选择IOS平台,很容易出现,切换到MAC/PC平台基本上就解决了,你不能要求在MAC下一定要运行IOS的动态库。LuaStudio,请使用Administrator管理员权限,否则会挂死!!!lua中用UIButton.current 确定单击哪个按钮//转自 阿诚de窝
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: