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 }