xlua, 不但可以做纯lua的逻辑更新,还可以做 C# 代码的bug hotfix.
就是可以在保持项目使用C#逻辑开发的前提下,出现bug后使用lua来修复.听起来很棒棒.
github地址 : xlua
试用一下之后,发现xlua的hotfix原理也很简单, 就是通过反射取出打上了 [hotfix] 标记的类,
然后对需要fix的函数执行下列伪代码
1
2 3 4 5 6 7 |
void Start
(
)
{ if (_hotfix ) _lua_add (a,b ) ; else _csharp_add (a,b ) ; } |
那么思路就来了.
设定一个全局 hotfix管理类, 在游戏初始化的时候拉取服务器的 hotfix 版本号, 看看服务器上是否有新的补丁需要下载, 如果有,将补丁存到本地. 之后加载 补丁, 打补丁. 最后进入游戏.
首先是一个范例:
一个有bug的类
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
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 ( ) { } } |
错误有 A,B 没有初始化
Add函数被写成了减法
好在类的开头被打上了 [Hotfix] 标记,让我们有机会热修复他.
然后是HotFix类
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
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 <VersionData > (versionData. text ) ; 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 ( ) { } } |
他会在游戏启动的时候去下载 http://www.dreamfairy.cn/xlua/test/version.txt 版本号数据
之后去补丁地址下载补丁文件 http://www.dreamfairy.cn/xlua/test/hotfix.lua
下载完毕后,缓存到本地, 然后调用游戏启动 StartUp
启动游戏后, 原本控制台输出 0 的结构, 热更新后 控制台输出 600
最后是lua部分的代码
1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
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 ) |
lua部分的代码,就3段 第一段 xlua.private_accessible(CS.FuckYouSelf)
让lua可以访问私有字段, 目的是为了改成员变量 A,B 他们是私有的
第二段是修改 类中的 Init函数, 来初始化A,B
第三段是修改 类中的 Add函数,让他正确执行加法