使用xlua 进行Unity3D 热更新

本文介绍xlua在Unity中实现热更新的原理及实践过程,包括如何使用xlua进行bug修复,通过反射机制加载带有[hotfix]标记的类,并在游戏启动时检查并应用服务器上的最新补丁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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函数,让他正确执行加法

--------------------- 本文来自 YOLO_TO_GAME 的优快云 博客 ,全文地址请点击:https://blog.youkuaiyun.com/weixin_39706943/article/details/80596800?utm_source=copy 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值