XLuahotfix

XLua

XLua下载以及配置

https://github.com/Tencent/Xlua 下载最新版Xlua。解压缩后将Assets文件夹下内容拷贝到自己工程的Assets目录中,将Tools拷贝到自己工程Assets同级目录中。

IDE配置

  • 打开HOTFIX_ENABLE宏,打开方法为点击 File->BuildSetting, 选择Player,点击Player Setting,在右边Inspector窗口的Scripting Define Symbols* 输入框中输入 HOTFIX_ENABLE
  • 执行XLua/Generate Code菜单
  • 在编辑器模式执行XLua/Hotfix Inject In Editor。 在打包手机模式不需要手动执行,会自动执行。

约束

  • 不支持静态构造函数。
  • 不支持在子类override函数通过base调用父类实现。
  • 目前只支持Assets下代码的热补丁,不支持引擎,c#系统库的热补丁。

API

xlua.hotfix(class, [method_name], fix)

  • 描述 : 注入lua补丁
  • class : C#类,两种表示方法,CS.Namespace.TypeName或者字符串方式"Namespace.TypeName",字符串格式和C#的Type.GetType要求一致,如果是内嵌类型(Nested Type)是非Public类型的话,只能用字符串方式表示"Namespace.TypeName+NestedTypeName";
  • method_name : 方法名,可选;
  • fix : 如果传了method_name,fix将会是一个function,否则通过table提供一组函数。table的组织按key是method_name,value是function的方式。

xlua.private_accessible(class)

  • 描述 : 让一个类的私有字段,属性,方法等可用
  • class : 同xlua.hotfix的class参数

标识要更新的类信息

可以直接在类上方加上热更新标签。

using UnityEngine;
using System.Collections;
using XLua;

[Hotfix(HotfixFlag.Stateless)] //Hotfix标识
public class Quit : MonoBehaviour {

    void Update () {
        if(isTouched()) {
            testHotfix();
        }
    }

    public bool isTouched() {
        bool result = false;
        if(Input.touchCount == 1) {
            if(Input.touches[0].phase == TouchPhase.Ended) {
                Vector3 wp = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
                Vector2 touchPos = new Vector2(wp.x, wp.y);
                if (GetComponent<Collider2D>() == Physics2D.OverlapPoint(touchPos)) {
                    result = true;
                }
            }
        }
        if(Input.GetMouseButtonUp(0)) {
            Vector3 wp = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            Vector2 mousePos = new Vector2(wp.x, wp.y);
            if (GetComponent<Collider2D>() == Physics2D.OverlapPoint(mousePos)) {
                result = true;
            }
        }
        return result;
    }

    public void testHotfix()
    {
        Debug.Log("Raw  hotfix value");
    }

}

或者在一个static类的static字段或者属性里头配置一个列表。属性可以用于实现的比较复杂的配置,比如根据Namespace做白名单。

public static class HotfixCfg
{
    [Hotfix]
    public static List<Type> by_field = new List<Type>()
    {
        typeof(HotFixSubClass),
        typeof(GenericClass<>),
    };

    [Hotfix]
    public static List<Type> by_property
    {
        get
        {
            return (from type in Assembly.Load("Assembly-CSharp").GetTypes()
                    where type.Namespace == "XXXX"
                    select type).ToList();
        }
    }
}

HotFix后可以加一个标志,HotfixFlag.Stateless或者HotfixFlag.Stateful, 如果不加默认为Stateless模式。在Stateless模式下,C#对象直接作为hotfix函数的self参数,即第一个参数。在Stateful模式下,可以在hotfix的构造函数中返回一个table,其他的hotfix函数的self参数为构造函数返回的table;如果未在lua中定义构造函数,则self为nil。

实例

上述的Quit.cs,对应的hotfix代码如下:

--[[     
-- 第一种hotfix方式
xlua.hotfix(CS.Quit, 'testHotfix',  function(self)
        print('Lua hotfix value')
    end
)
--]]

-- 第二种hotfix方式,一次替换整个类

xlua.hotfix(CS.Quit, {
    Update = function(self)
        if (self:isTouched(self)) then
            self:testHotfix()
            --CS.UnityEngine.Application.LoadLevel("level_1");
        end
    end;

    testHotfix = function(self)
        print('Lua hotfix value 2')
    end
})

可以在Scene中创建一个空Object,在这个空对象上绑定一个C#脚本,再在脚本里面从网络上下载最新hotfix assetbundle,如上ScriptLoader.cs的例子。

参考资料

posted @ 2017-12-04 16:30  何人之名  阅读(850)  评论(0)    收藏  举报