Unity HybridCLR热更新二 : 使用CatAssetManagr加载热更新



参考文档: 在Unity中构建AssetBundle补丁包 作者: 仙猫洞


使用   CatAssetManager.BatchLoadAssetAsync 批量加载需要热更的程序集

List<string> AOTMetaAssemblyFiles;  //热更dll的AssetBundle的地址

CatAssetManager.BatchLoadAssetAsync( AOTMetaAssemblyFiles ).OnLoaded += OnAotMetaAssemblyFilesLoaded;

加载AOT元数据

    private static void Run( )
    {

        Log.Green( "执行热更新后的代码" );
#if !UNITY_EDITOR
        _hotUpdateAss = Assembly.Load( HotUpdateBytes );
#else
        _hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies( ).First( a => a.GetName( ).Name == "HotUpdate" );
#endif
        Type entryType = _hotUpdateAss.GetType( "HotService" );
        entryType.GetMethod( "Update" ).Invoke( null, null );
        AotCompletedCallback?.Invoke( );
    }

    #region HotFix

    private static Assembly _hotUpdateAss;

    public Assembly GetAssembly( )
    {
        return _hotUpdateAss;
    }

    private static void OnAotMetaAssemblyFilesLoaded( BatchAssetHandler handler )
    {
        Log.Green( "AOT元数据加载完毕" );
        /// 注意,补充元数据是给AOT dll补充元数据,而不是给热更新dll补充元数据。
        /// 热更新dll不缺元数据,不需要补充,如果调用LoadMetadataForAOTAssembly会返回错误
        /// 
        handler.Handlers.ForEach( h =>
        {
            var asset = h.AssetAs<TextAsset>( );
            if ( asset != null )
            {
                // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
                LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly( asset.bytes, HomologousImageMode.SuperSet );
                Debug.Log( $"LoadMetadataForAOTAssembly:{h.Name}. mode:{HomologousImageMode.SuperSet} ret:{err}" );

                if ( h.Name.EndsWith( "HotUpdate.dll.bytes" ) )
                {
                    HotUpdateBytes = asset.bytes;
                }
            }
        } );

        //加载配置并启动游戏
        Run( );
    }

    #endregion


HotService.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HotService 
{
    public static void Update( )
    {
        Log.Green( "已加载热更新程序集" );

    }
}


Log
.cs

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
using Debug = UnityEngine.Debug;

/**
 * 
 * 
 * Log Utils 
 * 
 * General log management
 * 
 * anchor: ChenJC
 * 
 * time: 2023/2/23
 * 
 */
public class Log
{

    [Conditional( "ENABLE_LOG" )]
    public static void Info( string msg, Object param = null )
    {
        if ( null == param )
        {
            Debug.Log( msg );
        }
        else
        {
            Debug.Log( msg, param );
        }
    }

    [Conditional( "ENABLE_LOG" )]
    public static void Info( object msg, Object param = null )
    {
        if ( null == param )
        {
            Debug.Log( msg );
        }
        else
        {
            Debug.Log( msg, param );
        }
    }

    [Conditional( "ENABLE_LOG" )]
    public static void Error( string msg, Object param = null )
    {
        if ( null == param )
        {
            Debug.LogError( msg );
        }
        else
        {
            Debug.LogError( msg, param );
        }
    }

    [Conditional( "ENABLE_LOG" )]
    public static void Error( object msg )
    {
        Debug.LogError( msg );
    }

    [Conditional( "ENABLE_LOG" )]
    public static void Assert( bool condition, string msg, Object param = null )
    {
        if ( null == param )
        {
            Debug.Assert( condition, msg );
        }
        else
        {
            Debug.Assert( condition, msg, param );
        }
    }

    [Conditional( "ENABLE_LOG" )]
    public static void Warning( string msg, Object param = null )
    {
        if ( null == param )
        {
            Debug.LogWarning( msg );
        }
        else
        {
            Debug.LogWarning( msg, param );
        }
    }

    [Conditional( "ENABLE_LOG" )]
    public static void Light( string msg, Object param = null )
    {
        string content = $"<color=#ffff00>{msg}</color>";
        if ( null == param )
        {
            Debug.Log( content );
        }
        else
        {
            Debug.Log( content, param );
        }
    }

    [Conditional( "ENABLE_LOG" )]
    public static void Green( string msg, Object param = null )
    {
        string content = $"<color=#00ff00>{msg}</color>";
        if ( null == param )
        {
            Debug.Log( content );
        }
        else
        {
            Debug.Log( content, param );
        }
    }

    //
    //[Conditional( "ENABLE_LOG" )]
    /// <summary>
    /// 系统数据 任何情况下都必须输出 请不要随意调用这个方法 仅在重要的地方调用
    /// </summary>
    /// <param name="msg"></param>
    /// <param name="param"></param>
    public static void PINK( string msg, Object param  )
    {
        string content = $"<color=#EF47D1>{msg}</color>";
        Debug.Log( content, param );
    }
    /// <summary>
    /// 系统数据 任何情况下都必须输出 请不要随意调用这个方法 仅在重要的地方调用
    /// </summary>
    /// <param name="msg"></param>
    public static void PINK( string msg )
    {
        string content = $"<color=#EF47D1>♥ ♥ ♥ {msg}</color>";
        Debug.Log( content );
    }
}



HybridCLR 功能扩展: 自动拷贝HotUpdate.dll文件到项目里并重命名后缀.bytes

Unity HyBridCLR接入

评 论