Unity3D遊戲開發之Lua的技能培訓

      下面咱們開始今天的Unity3D技能培訓。 咱們學習Unity3D培訓目標:讓U3D初學者能夠更快速的掌握U3D技術,自行製做修改素材,能夠獨立完成2D、3D小規模遊戲及網頁遊戲開發。git

 

 

        好了,下面咱們就來一塊兒學習在Unity3D項目中如何使用Lua語言吧,Unity3D基於Mono虛擬機,因此理論上.NET的類庫是能夠直接在Unity3D中使用的。但是考慮到Unity3D跨平臺的須要,咱們選擇的工具必須在各個平臺得到良好的支持。在前文中提到的LuaInterface理論上是能夠在Unity3D中使用的,但是因爲IOS不支持反射機制,因此這個類庫咱們沒法直接在Unity3D中使用的。。好了,咱們,如今來建立一個簡單地Unity項目:github

        第一步是下載UniLua:http://github.com/xebecnan/UniLua。將UniLua引用到項目中有兩種方法,一種是將該項目中的UniLua編譯成dll而後在Unity項目中使用,一種是將該項目中的UniLua直接複製到Unity 項目中,咱們這裏使用第二種方法,由於博主比較懶,呵呵。將UniLua的命名空間添加到咱們項目中,咱們就能夠開始動手寫程序了。不過這裏,博主想說的是Mono可能會致使的一個錯誤,估計是阿楠在寫這個項目的時候使用了.NET4.0以上的版本,而在.NET4.0以上的版本是支持默認參數的構造函數的。但是因爲Mono默認使用的是.NET3.5,因此在編譯項目的時候就會報錯,咱們能夠經過Project->Assembly-CSharp->Build->General將.NET的目標框架設爲4.0,這樣就能夠解決這個問題了。好了,下面咱們開始寫代碼啦,首先建立一個InvokeScript.cs的腳本:數組

[csharp] view plaincopyprint?
 
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using UniLua;  
  4.   
  5. public class InvokeScript : MonoBehaviour {  
  6.       
  7.     //Lua腳本文件,咱們將在C#調用該腳本  
  8.     public TextAsset LuaFile;  
  9.     //Lua虛擬機  
  10.     private ILuaState mLua;  
  11.   
  12.     void Start()  
  13.     {  
  14.         //初始化Lua虛擬機  
  15.         mLua=LuaAPI.NewState();  
  16.         //加載Lua標準庫  
  17.         mLua.L_OpenLibs();  
  18.         //引用一個靜態地C#庫  
  19.         mLua.L_RequireF(CSharpLib.CLASSNAME,CSharpLib.InitLib,false);   
  20.   
  21.         //執行Lua腳本  
  22.         mLua.L_DoString(LuaFile.text);  
  23.     }  
  24.   
  25.     void OnGUI()  
  26.     {  
  27.         if(GUILayout.Button("調用Lua腳本",GUILayout.Height(30)))  
  28.         {  
  29.             InvokeLua();  
  30.         }  
  31.         if(GUILayout.Button("調用C#腳本",GUILayout.Height(30)))  
  32.         {  
  33.             InvokeCSharp();  
  34.         }  
  35.     }  
  36.  
  37.     #region 調用C#腳本  
  38.     void InvokeCSharp()  
  39.     {  
  40.         //獲取方法並傳入參數  
  41.         mLua.GetGlobal("SumAndSub");  
  42.         mLua.PushInteger(12);  
  43.         mLua.PushInteger(8);  
  44.         mLua.PCall(2,4,0);  
  45.     }  
  46.     #endregion  
  47.      
  48.     #region 調用Lua腳本  
  49.     void InvokeLua()  
  50.     {  
  51.         //獲取Lua腳本中的arg1參數  
  52.         mLua.GetGlobal("arg1");  
  53.         //輸出arg1  
  54.         Debug.Log("Lua腳本中的變量arg1="+mLua.L_ToString(-1));  
  55.   
  56.         //獲取Lua腳本中的arg2參數  
  57.         mLua.GetGlobal("arg2");  
  58.         //輸出arg2  
  59.         Debug.Log("Lua腳本中的變量arg2="+mLua.L_ToString(-1));  
  60.   
  61.         //獲取Lua腳本中的Printf方法  
  62.         mLua.GetGlobal("Printf");  
  63.         //調用Lua腳本中的Printf方法  
  64.         mLua.PCall(0,0,0);  
  65.   
  66.         //獲取Lua腳本中的Sum方法  
  67.         mLua.GetGlobal("Sum");  
  68.         //傳入參數12和25  
  69.         mLua.PushInteger(12);  
  70.         mLua.PushInteger(25);  
  71.         //調用此方法  
  72.         mLua.PCall(2,3,0);  
  73.         //獲取傳入的兩個參數及求和結果  
  74.         int a=mLua.ToInteger(-3);  
  75.         int b=mLua.ToInteger(-2);  
  76.         int sum=mLua.ToInteger(-1);  
  77.         //輸出  
  78.         Debug.Log("調用Lua腳本中的Sum方法:"+a+"+"+b+"="+sum);  
  79.     }  
  80.     #endregion  
  81.       
  82. }  
[csharp] view plaincopyprint?
 
  1.   

在這段腳本中,咱們首先初始化了Lua環境,這一點和咱們在C++中使用Lua是同樣的,由於UniLua在設計API的時候在命名上和LuaAPI保持了高度的一致,若是你對Lua API足夠熟悉的話,那麼如今這一切對你而言應該會很簡單的。接下來,咱們經過Require的形式引入了咱們編寫的一個C#庫,它是一個靜態庫,目的是封裝C#方法以便於Lua腳原本調用,這一部分咱們稍後會講到。接下來,咱們經過Unity的AssetText加載了一個Lua腳本文件,該腳本的文件的擴展名是.txt,由於咱們只須要Lua腳本的內容。在腳本中咱們定義了兩個方法InvokeLua和InvokeSharp來分別調用Lua腳本和C#腳本。好了,接下來,咱們重點來說Lua調用C#腳本的這部分,由於UniLua在調用函數這塊兒和LuaInterface不太同樣,因此咱們不能再用原來的先註冊C#方法而後再像Lua腳本方法同樣,不過這裏的原理是同樣的,不過UniLua提供了更好的方法綁定機制,咱們來看下面的腳本:框架

[csharp] view plaincopyprint?
 
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using UniLua;  
  4.   
  5. public static class CSharpLib  
  6. {  
  7.     //當前類文件名稱,咱們將在Lua腳本中使用這個名稱  
  8.     public const string CLASSNAME="CSharpLib.cs";  
  9.   
  10.     //C#庫初始化  
  11.     public static int InitLib(ILuaState lua)  
  12.     {  
  13.         NameFuncPair[] define=new NameFuncPair[]  
  14.         {  
  15.             new NameFuncPair("SumAndSub",SumAndSub),  
  16.         };  
  17.         lua.L_NewLib(define);  
  18.           
  19.         return 1;  
  20.     }  
  21.   
  22.     //咱們在C#中定義一個求和差的方法  
  23.     public static int SumAndSub(ILuaState lua)  
  24.     {  
  25.         //第一個參數  
  26.         int a=lua.L_CheckInteger(1);  
  27.         //第二個參數  
  28.         int b=lua.L_CheckInteger(2);  
  29.         //計算和  
  30.         int c=a+b;  
  31.         //計算差  
  32.         int d=a-b;  
  33.           
  34.         //將參數及計算結果壓入棧  
  35.         lua.PushInteger(a);  
  36.         lua.PushInteger(b);  
  37.         lua.PushInteger(c);  
  38.         lua.PushInteger(d);  
  39.           
  40.         //有四個返回值, 儘管在C#中不支持返回多個值,但是在Lua中這樣是支持的  
  41.         return 4;  
  42.     }  
  43. }  

你們必定注意到這裏有個NameFuncPair類吧,這就是在UniLua中用來將一個C#方法和Lua方法進行綁定的方法,咱們首先構造這樣一個NameFuncPair數組,而後將其加入到lua_L_NewLib()的參數中,這樣至關因而註冊了一個庫,我以爲應該就是註冊了一個方法集合吧.而CLASSNAME是一個表示當前類名稱的常量,能夠取任意字符,這裏咱們使用該類的文件名咱們將在Lua腳本是用這個值來查找當前類.接下來,咱們能夠看到博主構造了一個求和差的C#方法,這個方法和Lua API中定義的方法是一致的,即咱們須要指定該方法會返回的值得數目.若是咱們須要返回一個值,就要把它經過push系列的方法壓入棧中.這裏咱們返回了四個值,你們必定會問好是C#還支持返回多個值啊,其實呢,這是Lua語言提供給咱們的一個福利啊,好比咱們須要返回一個物體在3D世界裏的座標,一般狀況下,咱們須要用三個賦值語句才能獲取吧,但是你用Lua的話,一行代碼就能夠搞定啦.好,如今咱們回到InvokeScript腳本的Start方法中,你們能夠注意到這裏有一個L_RequireF()的方法,前面只是輕描淡寫地說它引入了一個庫,那麼如今咱們看看它具體作了什麼吧,第一個參數表示這個類的名字,指向咱們定義好的CLASSNAME,第二個參數是這個類的初始化方法指向InitLib()方法,第三個參數是是否要在全局空間中使用這個庫,這裏咱們選在false.好了,這樣,咱們就完成了C#腳本的編寫.好了,下面咱們在項目中建立一個純文本文件,咱們輸入以下代碼:函數

[plain] view plaincopyprint?
 
  1. local csharplib=require"CSharpLib.cs"  
  2. arg1="Unity3D"  
  3. arg2="Unreal"  
  4. arg3="Coco2dX"  
  5.   
  6. function Printf()  
  7.   print("This is the methods invoked in Lua")  
  8. end  
  9.   
  10. function Sum(a,b)  
  11.   return a,b,a+b  
  12. end  
  13.   
  14. function SumAndSub(a,b)  
  15.   print(csharplib.SumAndSub(a,b))  
  16. end  

第一行代碼一樣是一個require的方法,這是Lua腳本中引用一個庫的方法,該方法能夠引用Lua的標準庫,一樣能夠引用咱們定義的外部庫,你們注意到這裏的名字和咱們以前定義的CLASSNAME是同樣的,由於咱們就是經過這個名字來查詢這個庫的,咱們在Lua環境中註冊了這個庫,因此如今才能夠引用這個庫.在這段腳本中咱們定義了幾個字符型的變量,兩個Lua方法,一個用Lua包裝的C#方法.好了,如今咱們將這個文本文件指定到InvokeScript的LuaFile字段,咱們經過LuaFille的text獲取腳本內容,而後經過DoString()方法來執行腳本中的內容,注意這裏要先對C#庫進行註冊,而後再執行腳本中的內容,不然會出現錯誤.好了,最後,咱們來一塊兒看看運行效果吧:工具

你們能夠看到C#調用的Lua腳本中咱們獲取了腳本中的兩個變量arg一、arg2,調用了Lua中定義的兩個方法,而最後一個方法,如咱們所願,它返回了四個值,這正是咱們所但願的結果.這裏順便說一下啊,在Lua中的print方法和return在Call之後是能夠直接在Debug中輸出結果的,無需咱們再去作Log。更多精彩unity3d技術文章請點擊 http://www.gopedu.com/article學習

相關文章
相關標籤/搜索