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");
}
}