1. 程式人生 > >unity ulua使用方法一

unity ulua使用方法一

概念

熱更新指的是在不關閉伺服器的前提下,對上線的專案進行修改。
Lua程式碼都是執行時才編譯的,不執行的時候就如同一張圖片、一段音訊一樣,都是檔案;所以更新邏輯只需要更新指令碼,不需要再編譯,因而Lua能輕鬆實現“熱更新”。Ulua是一款非常實用的unity外掛,它能讓unity支援Lua語言,而且執行效率還不錯。

Unity 的原生c#是無法在移動端上進行熱更新的,那麼如果線上釋出遇到重大閃退事故的話,那麼就不可以通過遊戲內的熱更新進行bug修復,只能重新提交版本,而往往在提交版本到釋出的時間內,必然有玩家遇到這種問題,導致流失的,對於團隊來說,這個可是很嚴重的。

unity的熱更新可以通過釋出dll動態連結庫的方式進行線上更新,也可以通關lua進行更新。dll的反射機制在蘋果平臺不被支援,因此大多數情況都採用lua進行熱更新。

在unity中呼叫lua

unity中,使用lua的過程一般為:例項化LuaState物件(newLuaState()) ——> 載入Lua程式碼(LuaState.DoString(string)) ——>呼叫Lua程式碼中的方法( luaState.GetFunction(funcName).call(param))

lua指令碼 test0.lua

config={name="小阿哥",age=24,qq="247124629"};  

Name="小阿哥";  
Age=24;  
isBoy=true;  

function PrintFromLua
(a)
print("列印資訊。我來息LUA...CS傳的引數的值:",a); return 200; end print("test0.lua執行完畢..");

在C#中呼叫lua的屬性、方法

 void testCSharp_GoLuaInfor()  
    {  
        LuaState lua=new LuaState();  
        lua.DoFileFromAge(this,"Test0.lua",delegate(object[] obj) {  
            //訪問LUA中的表  
            LuaTable configTable=lua.GetTable
("config"); Debug.Log("name:"+configTable["name"]); Debug.Log("age:"+configTable["age"]); Debug.Log("qq:"+configTable["qq"]); //訪問LUA中的基礎屬性 Debug.Log("Name:"+lua.GetString("Name")); Debug.Log("Age:"+lua.GetNumber("Age")); Debug.Log("isBoy:"+lua["isBoy"]); //訪問Lua中的函式 LuaFunction luaFun=lua.GetFunction("PrintFromLua"); if(luaFun!=null) { System.Object[] obResult=luaFun.Call(100); Debug.Log("obResult:"+obResult[0]); } }); }

在lua中呼叫unity方法
關於Lua裡的預處理

luanet.load_assembly("Assembly-CSharp")

luanet.load_assembly('UnityEngine')

Vector2 = luanet.import_type('UnityEngine.Vector2')

Vector3 = luanet.import_type('UnityEngine.Vector3')

GameObject = luanet.import_type('UnityEngine.GameObject')

luanet.import_type('System.Collections.Generic.List')

Debug = luanet.import_type('UnityEngine.Debug')

這些都是常用的Lua預處理,建議單獨寫個Lua指令碼記錄這些,以後載入其他Lua指令碼前都先載入一下這個指令碼。自定義C#類也是可以import的,import操作是Lua呼叫C#的前提。當然在C#中例項化的LuaState也可以預定義一些Lua全域性變數,這都是在C#裡完成的,比如:


void SetLuaData(LuaState lua)

{

       lua["transform"] = transform;

       lua["gameObject"] = gameObject;

}

預定義了兩個變數,一個是transform,一個是gameObject。
lua 指令碼

luanet.load_assembly("Assembly-CSharp")
luanet.load_assembly('UnityEngine')
Vector2 = luanet.import_type('UnityEngine.Vector2')
Vector3 = luanet.import_type('UnityEngine.Vector3')
GameObject = luanet.import_type('UnityEngine.GameObject')
luanet.import_type('System.Collections.Generic.List')
Debug = luanet.import_type('UnityEngine.Debug')


prompt = transform:GetComponent('LuaBehaviour') 


function Awake(message)
    print(gameObject.name)--列印物件名稱
     Debug.Log(121121)--呼叫unity靜態方法,列印日誌
     prompt:test1()--呼叫指令碼方法
     print(Vector3.one)--呼叫靜態屬性
    return message

end

C#指令碼LuaBehaviour.cs

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using LuaInterface;

public class LuaBehaviour : MonoBehaviour {

    private string data = null;
    private Dictionary<string, LuaFunction> buttons = new Dictionary<string, LuaFunction>();
    LuaState l;

    public TextAsset text;//lua指令碼,txt格式物件


    protected void Awake()
    {
        initScript(text.ToString());
        CallMethod(name, "Awake");
    }

    void initScript(string script) {
         l = new LuaState();
         SetLuaData(l);
        l.DoString(script);


    }

    void SetLuaData(LuaState lua)
    {
        lua["transform"] = transform;
        lua["gameObject"] = gameObject; 
    }


    void CallMethod(string name, string methordName)
    {
       //獲取lua方法 
        LuaFunction f = l.GetFunction(methordName);
        //執行lua方法
        object[] r = f.Call("I called a lua function!");
    }


   public void test1() {

        Debug.Log("unity methord test1");
    }
}