Unity IL2CPP发布64位,以及代码裁剪Strip Engine Code

发布时间:2026/7/28 15:15:39

Unity IL2CPP发布64位,以及代码裁剪Strip Engine Code 万人同屏插件获取体验Demo下载万人同屏插件是一款通用的Unity性能优化插件是实现千人同屏、万人同屏的必备插件直击性能消耗痛点功能将2D Spine和3D动画性能十倍至百倍提升Jobs多线程移动避让和索敌算法以及兼容全平台的高性能渲染器。万人同屏插件兼容Unity全平台包括WebGL(2.0)微信/抖音小游戏等平台同样大幅性能翻倍Unity万人同屏集成方案Pro 支持微信小游戏PC店铺https://efunstudio.cnhttps://efunstudio.cn/性能/功能/红蓝对抗测试Demo Web在线体验https://assets.efunstudio.cnhttps://assets.efunstudio.cn/插件核心功能图网页版在线测试性能▷幸存者Demo▷性能测试Demo正文代码裁剪配置工具https://blog.csdn.net/final5788/article/details/126451377Google Play要求从2019年8月1日起apk必须支持64位CPU, 否则就下架或不让上. 使apk支持ARM64就需要把Scripting Backend由Mono切换为IL2CPP那么问题来了, 通过IL2CPP打出的包往往不能正常运行(闪退,报错).其原因就是, BuildSetting里默认勾选了代码裁剪, 取消勾选打出的apk就能正常运行,但是包体也会很大:什么是代码裁剪?关于代码裁剪的说明: Managed code stripping勾选代码裁剪,构建时Unity代码裁剪工具会分析项目中的程序集,查找和删除未使用的代码. 裁剪掉没有使用到的代码.比如,一款2D游戏只用到了Sprite, 2D物理组件, 就可以把没有用到的3D物理代码部分裁剪掉. 使用裁剪功能可以显著减小包体大小, 也是目前Unity游戏包体优化的一个重要环节.看起来确实是一个非常牛掰又实用的功能, 然而还有不少问题Unity貌似只能正确裁剪那些构建时自动打包进apk的预制体和场景中的脚本. 而AssetBundle上的脚本就就不会被处理到, 也就是说如果Prefab被打包成AssetBundle, 这个Prefab上的代码可能会被裁剪掉, 导致运行的时候报错闪退, 这无疑是致命的。所以Unity提供了裁剪等级的设置, 以及通过配置link.xml告诉Unity需要保留哪些代码.① Managed Stripping Level:有三个等级, 当然, 等级越高裁剪掉的代码越多, 包体也就越小, 但是对应的风险也就更大:② 配置link.xml:在项目的Assets目录下创建个link.xml首先, 我自己的写的游戏逻辑代码肯定需要全部保留, 项目用到了DOTween和Newtonsoft.Json插件也不需要裁剪掉, 就在link.xml添加如下:?xml version1.0 encodingUTF-8? linker assembly fullnameDOTween preserveall / assembly fullnameNewtonsoft.Json preserveall / assembly fullnameAssembly-CSharp preserveall / /linker上面的配置表示保留整个程序集dll, 也可以指定保留某个程序集里的某个类这样能更加精准控制保留哪个类从而尽可能裁剪掉没用到的类以减少程序集大小, 例如:assembly fullnameUnityEngine type fullnameUnityEngine.SpriteRenderer preserveall/ type fullnameUnityEngine.Rigidbody2D preserveall/ /assembly还有很多其它配置规则请参考官方文档.Ok, 已经了解到代码裁剪的一点皮毛, 那就开始往坑里跳吧.0.不进行代码裁剪, apk能正常运行, apk大小为44.5M1.设置IL2CPP,并勾选代码裁剪,设置裁剪等级为Low, 先不做link.xml配置. 打包apk大小为39.4M. 运行, 完美闪退. Logcat:很明显, 有的类在项目中使用过,但被裁剪掉了. 并且还给了贴心提示, 让尝试禁用代码裁剪.闪退问题找到了, 理论上我们把使用到的类配置到link.xml, 防止被裁剪掉就行了. 但是, 怎么找到这些使用到的类呢?可以看到上图圈出部分, 可以知道这个被裁剪掉的类ID是233, OK, 我们从YAML Class ID Reference找找看:项目Prefab中用到了HingeJoint2D组件, 但是被Unity裁剪掉了, 所以当游戏运行到实例化这个Prefab时就报错闪退了.嗯, 感觉有戏. 再找下一个被裁掉的类ID为253, 翻啊翻啊,竟然没找到! 好吧, 应该不是Unity的类. 但是一个一个去找类名感觉有点傻. 这时候就需要上篇博文介绍到的编辑器扩展知识让程序把那些用到过的Unity类给提取出来, 然后配置到link.xml里, 防止被裁剪掉.同样, 原理也是超简单, 遍历查找所有Prefab上的节点, 获取节点上的组件把类名记录到文件里:public static void FindAllScripts() { EditorUtility.DisplayProgressBar(Progress, Find Class..., 0); string[] dirs { Assets/MainGame/Prefabs }; var asstIds AssetDatabase.FindAssets(t:Prefab, dirs); int count 0; Liststring classList new Liststring(); for (int i 0; i asstIds.Length; i) { string path AssetDatabase.GUIDToAssetPath(asstIds[i]); var pfb AssetDatabase.LoadAssetAtPathGameObject(path); foreach (Transform item in pfb.transform) { var coms item.GetComponentsInChildrenComponent(); foreach (var com in coms) { string tName com.GetType().FullName; if (!classList.Contains(tName) (tName.StartsWith(UnityEngine) || tName.StartsWith(TMPro))) { classList.Add(tName); } } } count; EditorUtility.DisplayProgressBar(Find Class, pfb.name, count / (float)asstIds.Length); } for (int i 0; i classList.Count; i) { classList[i] string.Format(type fullname\{0}\ preserve\all\/, classList[i]); } System.IO.File.WriteAllLines(Application.dataPath /ClassTypes.txt, classList); EditorUtility.ClearProgressBar(); }生成文件如下, 然后复制到link.xml即可:最终link.xml配置好了:?xml version1.0 encodingUTF-8? linker assembly fullnameDOTween preserveall / assembly fullnameNewtonsoft.Json preserveall / assembly fullnameAssembly-CSharp preserveall / assembly fullnameUnityEngine type fullnameUnityEngine.Transform preserveall/ type fullnameUnityEngine.SpriteRenderer preserveall/ type fullnameUnityEngine.Rigidbody2D preserveall/ type fullnameUnityEngine.CapsuleCollider2D preserveall/ type fullnameUnityEngine.CircleCollider2D preserveall/ type fullnameUnityEngine.HingeJoint2D preserveall/ type fullnameUnityEngine.FixedJoint2D preserveall/ type fullnameUnityEngine.BoxCollider2D preserveall/ type fullnameUnityEngine.ParticleSystem preserveall/ type fullnameUnityEngine.ParticleSystemRenderer preserveall/ type fullnameUnityEngine.DistanceJoint2D preserveall/ type fullnameUnityEngine.MeshFilter preserveall/ type fullnameUnityEngine.MeshRenderer preserveall/ type fullnameUnityEngine.BuoyancyEffector2D preserveall/ type fullnameUnityEngine.PolygonCollider2D preserveall/ type fullnameUnityEngine.Experimental.U2D.SpriteShapeRenderer preserveall/ type fullnameUnityEngine.U2D.SpriteShapeController preserveall/ type fullnameUnityEngine.EdgeCollider2D preserveall/ type fullnameUnityEngine.SpringJoint2D preserveall/ type fullnameUnityEngine.AreaEffector2D preserveall/ type fullnameUnityEngine.SurfaceEffector2D preserveall/ /assembly /linker这里需要注意的是link.xml配置是根据程序集而不是根据名字空间例如UnityEngine.Animator在VisualStudio中跳转到Animator类会发现它是属于UnityEngine.AnimationModule程序集而不是UnityEngine程序集。如果配置到错误的程序集自然就不能正确保留该类防止被裁剪。如保留Animator类如下方式是无效的assembly fullnameUnityEngine preserveall/正确方式应该是assembly fullnameUnityEngine.AnimationModule preserveall/Unity项目Build后会在项目Library的子目录如Library\Bee\artifacts\Android\ManagedStripped下生成项目依赖的全部程序集(不同版本Unity或不同平台生成程序集位置不同)这样就可以确定需要保留哪些程序集。管它三七二十四的, 打个包验证一下. 一步到位, 把裁剪等级为High, 得到apk大小39.7M,经测试运行正常. 比不做代码裁剪小了4.8M. 如果哪位路过的大佬知道更简单的有效的方式还请赐教?

相关新闻