概念
热更新指的是在不关闭服务器的前提下,对上线的项目进行修改。
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");
}
}
参考:http://blog.csdn.net/ybhjx/article/details/50930408
http://www.cnblogs.com/lifesteven/p/5126604.html