之前一直在纠结项目的某些运营界面使用全Lua来写,这样可以热更新上线不同的活动,而不需要上架不同的版本,虽然可以通过资源更新加载xml的方式来实现,但是要通过xml来组合一些新的活动逻辑会很困难.
然后听了很多朋友最近都在推荐xlua, 不但可以做纯lua的逻辑更新,还可以做 C# 代码的bug hotfix.
就是可以在保持项目使用C#逻辑开发的前提下,出现bug后使用lua来修复.听起来很棒棒.
github地址 : xlua
试用一下之后,发现xlua的hotfix原理也很简单, 就是通过反射取出打上了 [hotfix] 标记的类,
然后对需要fix的函数执行下列伪代码
[cc lang=”C++”]
void Start()
{
if(_hotfix)
_lua_add(a,b);
else
_csharp_add(a,b);
}[/cc]
那么思路就来了.
设定一个全局 hotfix管理类, 在游戏初始化的时候拉取服务器的 hotfix 版本号, 看看服务器上是否有新的补丁需要下载, 如果有,将补丁存到本地. 之后加载 补丁, 打补丁. 最后进入游戏.
正好以前自己写过好几个lua项目比如 : PrompaLua, lua还没忘记..正好用上 哈哈
首先是一个范例:
一个有bug的类
[cc lang=”C++”]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
[Hotfix]
public class FuckYouSelf : MonoBehaviour {
private int A;
private int B;
void Init() {
}
// Use this for initialization
void Start () {
Init();
UnityEngine.Debug.Log(Add(A, B));
}
int Add(int a, int b) {
return a – b;
}
// Update is called once per frame
void Update () {
}
}
[/cc]
错误有 A,B 没有初始化
Add函数被写成了减法
好在类的开头被打上了 [Hotfix] 标记,让我们有机会热修复他.
然后是HotFix类
[cc lang=”C++”]
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public class HotFix : MonoBehaviour {
public GameObject StartUp;
[Serializable]
struct VersionData {
public string Version;
public string FixUrl;
}
LuaEnv luaevn = new LuaEnv();
// Use this for initialization
void Awake () {
StartCoroutine(LoadVersion(“http://www.dreamfairy.cn/xlua/test/version.txt”));
}
IEnumerator LoadVersion(string versionUrl) {
WWW versionData = new WWW(versionUrl);
yield return versionData;
if(null != versionData.error) {
Debug.LogError(versionData.error);
} else {
VersionData data = JsonUtility.FromJson
StartCoroutine(LoadFix(data.FixUrl, data.Version));
}
}
IEnumerator LoadFix(string fixUrl, string version) {
//todo: check storage hotfix version
WWW fixData = new WWW(fixUrl);
yield return fixData;
if (null != fixData.error) {
Debug.LogError(fixData.error);
} else {
ApplyHotFix(fixData.text);
SaveToStorage(fixData.text, version);
}
}
void ApplyHotFix(string luastr) {
luaevn.DoString(luastr);
if(null != StartUp) {
StartUp.SetActive(true);
}
}
void SaveToStorage(string luastr, string version) {
//todo
}
private void OnDestroy() {
}
}
[/cc]
他会在游戏启动的时候去下载 http://www.dreamfairy.cn/xlua/test/version.txt 版本号数据
之后去补丁地址下载补丁文件 http://www.dreamfairy.cn/xlua/test/hotfix.lua
下载完毕后,缓存到本地, 然后调用游戏启动 StartUp
启动游戏后, 原本控制台输出 0 的结构, 热更新后 控制台输出 600
最后是lua部分的代码
[cc lang=”lua”]
xlua.private_accessible(CS.FuckYouSelf)
xlua.hotfix(CS.FuckYouSelf, ‘Init’,
function(self)
self.A = 300
self.B = 300
end
)
xlua.hotfix(CS.FuckYouSelf, ‘Add’,
function(self, a, b)
return a + b
end
)
[/cc]
lua部分的代码,就3段 第一段 xlua.private_accessible(CS.FuckYouSelf)
让lua可以访问私有字段, 目的是为了改成员变量 A,B 他们是私有的
第二段是修改 类中的 Init函数, 来初始化A,B
第三段是修改 类中的 Add函数,让他正确执行加法