> 技术文档 > Unity安卓C#热更全流程详解_unity 安卓热更新

Unity安卓C#热更全流程详解_unity 安卓热更新

文章摘要

Unity热更流程核心步骤:1)将C#代码编译为DLL并作为TextAsset打包进AssetBundle;2)运行时下载AssetBundle并提取DLL;3)Mono模式直接反射调用,IL2CPP模式下需借助ILRuntime等框架;4)更新AssetBundle即可实现热更。关键点在于IL2CPP的限制处理及通过接口/反射实现代码交互,该方案支持代码和资源的热更新,是Unity安卓开发的常用方案。


1. 热更流程详细说明

步骤一:将热更代码编译成DLL

  • 用C#编写热更逻辑(比如新功能、修复bug的代码)。
  • 用Visual Studio等工具将这些代码编译成DLL(.dll文件)。

步骤二:以TextAsset形式打包到AssetBundle

  • 在Unity工程中,将DLL文件作为TextAsset资源导入。
  • 用AssetBundle打包工具(如Addressables、AssetBundle Build Pipeline)把TextAsset打包进AssetBundle包。

步骤三:运行时下载AssetBundle

  • 客户端启动时,从服务器下载最新的AssetBundle(包含DLL的TextAsset)。

步骤四:加载DLL并反射调用

  • 取出TextAsset.bytes,获得DLL的二进制数据。
  • Mono模式下:可以直接用Assembly.Load(byte[])加载DLL,然后用反射(Type.GetType、MethodInfo.Invoke等)调用热更代码。
  • IL2CPP模式下(安卓真机常用):不能直接加载DLL,需要用ILRuntime、HybridCLR等第三方热更框架来解释或AOT运行DLL中的代码。

步骤五:更新AssetBundle即可热更

  • 只需替换服务器上的AssetBundle(含新DLL),客户端下次启动或热加载时下载新包,即可实现热更新,无需重新打包APK。

2. 关键注意点

  • IL2CPP限制:安卓正式包通常用IL2CPP,不能直接Assembly.Load DLL,必须用ILRuntime、HybridCLR等热更框架。
  • 反射调用:热更代码和主工程代码的交互通常通过反射、接口、委托等方式实现。
  • 资源热更:除了代码DLL,其他资源(Prefab、贴图、音频等)也可以用AssetBundle热更。
  • 安全性:热更DLL要做好校验,防止被篡改。

3. 流程图

#mermaid-svg-AOqHKu1XVByqGYgG {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-AOqHKu1XVByqGYgG .error-icon{fill:#552222;}#mermaid-svg-AOqHKu1XVByqGYgG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AOqHKu1XVByqGYgG .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-AOqHKu1XVByqGYgG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AOqHKu1XVByqGYgG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AOqHKu1XVByqGYgG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AOqHKu1XVByqGYgG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AOqHKu1XVByqGYgG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AOqHKu1XVByqGYgG .marker.cross{stroke:#333333;}#mermaid-svg-AOqHKu1XVByqGYgG svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AOqHKu1XVByqGYgG .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-AOqHKu1XVByqGYgG .cluster-label text{fill:#333;}#mermaid-svg-AOqHKu1XVByqGYgG .cluster-label span{color:#333;}#mermaid-svg-AOqHKu1XVByqGYgG .label text,#mermaid-svg-AOqHKu1XVByqGYgG span{fill:#333;color:#333;}#mermaid-svg-AOqHKu1XVByqGYgG .node rect,#mermaid-svg-AOqHKu1XVByqGYgG .node circle,#mermaid-svg-AOqHKu1XVByqGYgG .node ellipse,#mermaid-svg-AOqHKu1XVByqGYgG .node polygon,#mermaid-svg-AOqHKu1XVByqGYgG .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AOqHKu1XVByqGYgG .node .label{text-align:center;}#mermaid-svg-AOqHKu1XVByqGYgG .node.clickable{cursor:pointer;}#mermaid-svg-AOqHKu1XVByqGYgG .arrowheadPath{fill:#333333;}#mermaid-svg-AOqHKu1XVByqGYgG .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AOqHKu1XVByqGYgG .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AOqHKu1XVByqGYgG .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-AOqHKu1XVByqGYgG .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-AOqHKu1XVByqGYgG .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AOqHKu1XVByqGYgG .cluster text{fill:#333;}#mermaid-svg-AOqHKu1XVByqGYgG .cluster span{color:#333;}#mermaid-svg-AOqHKu1XVByqGYgG div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-AOqHKu1XVByqGYgG :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}编写热更C#代码编译成DLL作为TextAsset导入Unity打包进AssetBundle上传到服务器客户端运行时下载AssetBundle提取DLL字节流用ILRuntime/HybridCLR等加载DLL反射/接口调用热更逻辑


4. 总结

将代码编译成dll, 然后以textAsset的形式打包到assetBundle中去,然后下载后使用反射技术进行访问,更新对应的assetBundle即可实现热更”是Unity安卓C#热更的主流方案
但在IL2CPP下,必须借助ILRuntime、HybridCLR等热更框架,不能直接Assembly.Load。
资源和代码都可以用AssetBundle热更,流程安全高效。