UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技 - build
1）Unity 2018发布在iOS 16.3偶尔出现画面不动的问题 2）IL2CPP在Xcode下增量编译问题 3）帧同步实现PuppetMaster布娃娃系统的问题 这是第351篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：community.uwa4d.com UWA QQ群：465082844 Platform Q：Unity 2018发布在iOS 16.3偶尔出现画面不动的问题。 项目持续时间很长了，还是用的2018版本。随着新iOS系统推出，这种反馈也越来越多，大部分都是出现在iOS 16.3.x。 具体表现是：画面完全不动，也不接收任何输入事件，像是渲染停了，但是逻辑还是正常，还在播放声音，刷怪之类的。 手上的iOS设备重现不了，也就没法调试。不知道是哪一块可能有问题，希望有遇到过的朋友分享经验，不胜感激。 A：之前在社区上也看到过跟上面这个情况是一样的问答，因为只有外网玩家反馈，公司的设备都不能重现，所以也不好定位。 要是能知道是Shader报错，那还能调试，参考这个： https://zhuanlan.zhihu.com/p/335293011 感谢zlfeng@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/64ad14019e99796cd233a4d4 Build Q：最近在研究加速打包问题，发现IL2CPP生成代码之后每次Xcode都是全量编译（直接build而不是clean+archive）。 我参考了以下信息： https://forum.unity.com/threads/incremental-builds-for-il2cpp.365470/ 对比了下如果C#代码没有变化，生成的CPP代码的内容确实不变。但是重新生成貌似会导致文件修改时间变化或别的属性变化，Xcode依然是所有都编译了一遍。 这块有什么经验吗？ A1：我之前的做法是细化打包策略，资源打包细分为差不多10个步骤：对UI、特效、Lua（分三块：Core、模块和LuaTable配置），C#层Config、角色、场景、编译工程、资源覆盖、快速编译、生成APK/IPA和云真机测试等，组织成不同的打包命令提供给CI。 如果是C#代码没变化，可以只做资源类的打包，对需要重新（此处可增量）打包的AssetBundle、Lua、Config等打包，打包后直接覆盖到Xcode工程，直接生成IPA包，跳过中间环节。 构建过程可以细化到很细，如果你是Lua侧，那估计只需要打包Lua模块相关，1分钟内就可以出到IPA包。 如果是Xcode代码也发生变化，这个可以结合Ccache进行提速。 资源打包可以做分布式打包，多台黑苹果去打包各个模块的资源。再传递到版本机上整合，这个过程也可以Hook Svn/Git的资源提交，在提交后做一次打包，再次发布的时候可以增量处理。 其实可以脱离AssetBundle，把量产资源采用非AssetBundle的方式进行组织。避开不必要的导入导出及打包。 感谢debugger@UWA问答社区提供了回答 A2：2年多前，刚好处理过这个问题，当时用的Ccache来缓存Xcode编译的中间产物，在打包后处理修改预处理文件Classes/Preprocessor.h的修改时间，在加速效果上是明显的，缩短了一半多的时间。 感谢海桐@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5b90ebbb670c1a61c64d6cd3 Physics Q：项目中用PuppetMaster插件做布娃娃效果，模拟障碍击打等等各种效果。目前服务器是基于状态同步实现，但同步量太大，考虑修改为帧同步的方式，但是PuppetMaster中大量使用了刚体组件、Joint组件去模拟各种效果。帧同步中刚体这块有什么办法实现吗？ A：如果是做帧同步，表现层和逻辑层一定要做分离。简单看了一下PuppetMaste这个插件，不太确定但是大概率是基于PhysX实现的，我们自己测试PhysX在相通平台（iOS或者Android）经过一些处理是基本可以保证一致性的，但是iOS和Android上我们测试出过非常明确的不一致现象，所以如果要做移动端跨平台的游戏，帧同步所管理的逻辑层最好不要使用PhysX物理引擎，否则无法保证最终的一致性。 当然，这里还要看题主的游戏类型，如果比较简单，而且每局很短时间，也许不一致的结果可控，可以尝试一下。整体上不推荐把这个插件做到帧同步的逻辑内，成本比较高。 感谢贾伟昊@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/648718bd47691b75be04aab4 封面图来源于网络 今天的分享就到这里。生有涯而知无涯，在漫漫的开发周期中，我们遇到的问题只是冰山一角，UWA社区愿伴你同行，一起探索分享。欢迎更多的开发者加入UWA社区。 UWA官网：www.uwa4d.com UWA社区：community.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：465082844
1）Unity升级后打包AssetBundle变慢 ​2）打包使有些资源合成了一个资源data.unity3d，有些分开的原因 3）Unreal在移动设备中无法使用Stat命令获取到GPU Thread的耗时 4）Unity中如何看到相机视野范围内的剔除结果 这是第330篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：community.uwa4d.com UWA QQ群：465082844 AssetBundle Q：最近升级到了2021，遇到个奇怪的问题。打AssetBundle包，前面的速度正常，打到场景的时候变的非常慢，每2个场景之间不知道为什么停了1分钟，几十个场景，加起来AssetBundle包不到20MB，打了1个半小时，如果我只打这些场景，速度就是正常的，完整打AssetBundle包到了场景这里就特别慢。 A：可以尝试用Scriptable Build Pipeline来打包，在输出目录可以看到json文件，用Perfetto可以打开这个文件看耗时信息。 https://docs.unity3d.com/Packages/com.unity.scriptablebuildpipeline@1.18/manual/BuildLogger.html 该问答由UWA提供，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6420fec76778221ae3074852 Build Q：为什么打出来的包有些是资源合成了一个资源data.unity3d，有些是分开的？ A1：可以看看是不是以下这个设置导致的： 感谢范世青@UWA问答社区提供了回答 A2：比较建议使用LZ4的压缩方式的，AUP上传纹理必须使用LZ4的压缩方式，TextureStreaming也依赖LZ4的压缩。 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/641c1a1b6778221ae3044550 Unreal Q：我在移动设备Android上，输入Stat Unit命令，结果显示： Frame：42.33ms Game：24.22ms Draw：42.22ms RHIT：25.00ms Mem：1.96GB Draws：496 Prims：545.33KB 为什么没有GPU的耗时显示呢？可能是什么原因？ 针对以上问题，有经验的朋友欢迎转至社区交流分享： https://answer.uwa4d.com/question/641d1ca66778221ae304da66 Rendering Q：Unity中如何看到相机视野范围内的物体？类似Unreal Engine的FreezenRendering功能，方便快速的定位视锥体剔除。 针对以上问题，有经验的朋友欢迎转至社区交流分享： https://answer.uwa4d.com/question/63b41cd03bd6691a9ddc485c 封面图来源于网络 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：465082844
安卓包在真机上安装时的“风险提示”问题
1）安卓包在真机上安装时的“风险提示”问题 ​2）iOS下AssetBundle的加载疑问 3）特效用粒子系统，模拟器里出现花屏问题 4）IL2CPP编译的Protobuf，反射类运行时报空 这是第321篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：answer.uwa4d.com UWA QQ群：465082844 Android Q：最近在安卓真机上安装游戏的过程中突然出现了风险提示（以前没有）。有的手机甚至需要输入密码授权才能安装。 如图： 不知道有没有大佬们最近也遇到了这样的问题，可否提供个修改的思路？ A：首先是32位问题，这个是必然要升级的不要挣扎了。至于风险提示和密码授权，都是国内手机的问题。Rom里面限制了你不上架它的商店就会有这种提示。OPPO限制了adb直接安装，每次要密码授权。这些都属于研发层面无从下手的问题。 感谢江南@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/63c13247fbd55360acbe4943 AssetBundle Q：iOS下AssetBundle加载时候Animator上面丢失AnimatorController。 问题： 1.0版本里A.prefab是打在AssetsBundle1里面，A.prefab引用的AnimatorController 是打在AssetsBundle2里面，A.prefab上引用的其他资源在AssetsBundle3里面。 2.0版本热更新时，改变了引用文件的文件夹，A.prefab上引用的AnimatorController生成的Bundle变到了AssetsBundle3里面，A.prefab上引用的其他资源生成的Bundle变到AssetsBundle2里面。 A.prefab所在的AssetsBundle1没有变化，所以热更新下去的是AssetsBundle2和AssetsBundle3。 热更新之后加载AssetsBundle2和AssetsBundle3，再加载AssetsBundle1，运行后发现A.prefab上的Animator组件还在，但是上面的runtimeAnimatorController丢失了，变成了Missing。 有人遇到这个问题吗？ A1：有一些排查思路，首先在Android平台看下是否也有问题，排除下是否是与平台相关。另外在出问题的机器上预制体模式，如果正常则使用AssetBundle模式来加载看下是否正常，如果是Bundle问题，那可以完全删除涉及到的Bundle重新打一遍再试一下。 感谢Knight-132872@UWA问答社区提供了回答 A2：Unity上遇到这种问题，最好把A、B、C 3个AssetsBundle包先删除，再打包，让Unity全新生成，应该就好了。 感谢1 9 7 3-311135@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/63bf72e3fbd55360acbca922 Simulator Q：游戏特效用了粒子系统，其他平台都正常，就在模拟器下出现了花屏问题，时不时地花屏闪烁。 特效用了粒子系统的Mesh和Billboard两种模式，然后粒子上挂材质球，是用自己写的Shader，但是切换成Unity自带的URP粒子系统Shader，也一样花屏。不用粒子系统就不会花屏。 用RenderDoc抓帧，只分析出部分花屏，是用Mesh模式的粒子网格，顶点发生拉扯偏移产生的。但是其余花屏，查不出是哪个对象产生的问题，谁知道是怎么回事吗？ A1：可以尝试换一下Shader的采样精度。 感谢NG週@UWA问答社区提供了回答 A2：可以尝试一下把粒子特效对应Shader变量类型从fixed改为half或者float。 感谢beikeshell@UWA问答社区提供了回答 针对以上问题，有经验的朋友欢迎转至社区交流分享： https://answer.uwa4d.com/question/634808f7e545ad1a45ba84be Build Q：IL2CPP编译的Protobuf，反射类运行时报空。 问题发生时，会闪崩，闪崩日志信息： Error_Not_Null:"c# exception:System.TypeInitializationException: The type initializer for ‘abcConfigReflection’ threw an exception. —> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —> System.ExecutionEngineException: Attempting to call method 'Google.Protobuf.Reflection.ReflectionUtil+ReflectionHelper`2[[System.IntPtr&, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]::.ctor’ for which no ahead of time (AOT) code was generated.\n ... （完整日志信息，请见原问答。） 看下来是因为AOT编译时，代码剔除所致，问题非常偶现。我们的QA基本上没有跑出来过这个问题，但是放到外网就有一堆玩家遇到此问题。蹊跷的是哪怕同一个手机也是偶然才报。 Proto GitHub项目有人提过这个问题，包括下面回复主要提了两点： 1. Linker包含Google.Protobuf程序集 2. AOT编译器不会为T为Any Enum的泛型方法，针对枚举参数泛型方法创建显式调用类 https://docs.unity3d.com/cn/current/Manual/ScriptingRestrictions.html 和我这个问题不同点是，abcConfigReflection是一个类，不是枚举，而且整个项目这个类会有很多。 我用的Proto 3.6.1版本，而且Proto也在3.6.0版本修改了 > AOT generics issues in Unity/il2cpp have a workaround (see commit 1b219a1 for details) Protobuf源码确实加了强制反射的代码： static FileDescriptor() { ForceReflectionInitialization<Syntax>(); ForceReflectionInitialization<NullValue>(); ForceReflectionInitialization<Field.Types.Cardinality>(); ForceReflectionInitialization<Field.Types.Kind>(); ForceReflectionInitialization<Value.KindOneofCase>(); } 当然我有加Google.Protobuf程序集到Linker，还是不能解决。后来我加了Assembly-CSharp程序集到Linker，也就是整个自定义代码全部不剔除，目前因为不方便放外网，也不清楚有没有解决这个问题。 使用Protobuf序列化数据按讲是常规操作，相信应该有很多人遇到，不知道大家处理方案是什么，有没有解决这个问题？ 针对以上问题，有经验的朋友欢迎转至社区交流分享： https://answer.uwa4d.com/question/63c4f6d1fbd55360acc178a7 封面图来源于网络 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：465082844
1）Shader Graph和Amplify Shader Editor有哪些区别 ​2）Canvas AdditionalShaderChannels设置无效 3）IL2CPP打包速率问题 4）SRP是否还需要图集 这是第290篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Shader Q：请教各位，Unity自带的Shader Graph或Amplify Shader Editor，在使用和生成的Shader性能问题上，除了Amplify Shader Editor目前自带Node功能的丰富度以及社区资源丰富度应该更胜一筹外，两者还有多少区别？ 项目背景：新项目（手游），基于Unity URP的二次元NPR+PBR，3D场景+3D角色。 A1：参考如下： 体验：Amplify Shader Editor优 使用：Amplify Shader Editor优 通用程度：Amplify Shader Editor优 兼容性：Shader Graph优 未来发展：Shader Graph优 结论：两个都用并不冲突，但是我倾向于优先使用Shader Graph慢慢替代Amplify Shader Editor。 感谢大崔-287520@UWA问答社区提供了回答 A2：实际体验上Amplify Shader Editor会比Shader Graph好用很多。 Amplify Shader Editor生成的是明文Shader文件，可以自行修改调整部分不合理的生成；Shader Graph也能看到他生成的Shader，但是设计上Unity尽量希望黑盒，不想让你看到。 Amplify Shader Editor可以几条管线互相切，Shader Graph只能在URP下使用。 Amplify Shader Editor兼容所有Shader Graph的节点和参数。 Shader Graph界面比Amplify Shader Editor好看，品控比较好，小bug没Amplify Shader Editor多。 每一步计算的节点结果，Shader Graph能预览基本所有的，Amplify Shader Editor如果是自己定义的管线全局参数以及有些内置的，不太好预览。 连连看这种生成的Shader质量都很差，基本需要效率的都得翻新一遍。 常见的优化，比如c=tex2d(uv) 紧接着使用c，是需要等待GPU操作显存回来的时间消耗。 这种一般会插入其他计算，抵消这个消耗。 比如： c = tex2d(uv) //do other thing c = c*c; 目前两种都是按节点逻辑生成，一个uv节点就会生成tex2d(uv)和后续计算的逻辑。 没有整体做语义分析的优化。 感谢uwa菜鸡奶泡泡.@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/620c9123e7172c2775ea8f00 UGUI Q：在UI中使用到的Shader中用到了uv1和uv2通道，在Canvas AdditionalShaderChannels中选择添加了对应通道后没有效果，相同代码资源在2019.4.26f1c1正确显示，请教大家是否是版本问题还是需要特殊设置处理？ Unity版本：2018.4.17f1 A：在2018.4.23f1版本上参考这个链接的Outline效果进行了测试，在小米9真机上没有发现问题。 可以参考一下《基于Shader实现的UGUI描边解决方案》。 PS：看了一下2018.4.18到2018.4.23之间的所有的Release Note，没有发现相关问题的修复。这个文章是使用Shader来实现Outline的，感觉效果挺不错的。 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6228644a80139e0c1f1f661a Build Q：最近在使用12700f的丐版电脑，发现打包（IL2CPP）速度比5950x快了20%（472s对比621s，同工程）。 不知道大家有没有对比过十二代Intel，如果真的这么好，新电脑可以全面十二代Intel加b660了。 补充：内存都足够，没有用到页面缓存。 A：按照官方的说法，IL2CPP在2020.2.0b2之前都是单线程的，AMD的CPU一般是多线程强，Intel的单线程强，所以可以根据Unity版本选择最佳的CPU类型。 官方说法： https://forum.unity.com/threads/il2cpp-player-build-time-improvement-coming-to-2020-2-0b2.963614/ 感谢张迪@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6228b4b280139e0c1f1fdc90 Rendering Q：查看了官网的描述：SRP Batch会批处理GPU命令，将Draw Call降低下来。 经过我们反复的FrameDebug测试，即使在不同的材质、不同的贴图和不同的颜色，但只要Shader以及Shader变体是同一个则可以合并批次。 那么我们是否还有必要打包图集？ A：使用SPR Batcher的注意事项： 需要是同一个Shader、同一个变体，可以是不同的材质球，项目需要使用自定义渲染管线，Shader代码必须兼容SRP Batcher。 SRP Batcher不支持MaterialPropertyBlock。 参考《使用MaterialPropertyBlock来替换Material属性操作》。 参与SRP Batcher的渲染物体必须是一个Mesh或者Skinned Mesh。所以，粒子和UI上用到的纹理还是需要打包图集。 感谢Faust@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/622ac7a780139e0c1f22cf03 封面图来源于：Command Buffer Refraction 使用Amplify Shader Editor创建的，使用了Command Buffers的模糊折射着色器。 适用于表现玻璃材质，无需使用Amplify Shader Editor就可以运行工程。 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：793972859（原群已满员）
1）Unity将核心脚本打成DLL是否有性能影响 ​2）预制物嵌套导致AssetBundleName修改后对母预制物丢失引用 3）真人真机测试报告中AB.LoadFromFile耗时较高 4）如何剔除掉Shader中某一个Pass 这是第287篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Build Q：Unity将核心脚本打成DLL，比如将某块核心系统打成DLL后，运行时调用DLL是否有性能影响？ A1：没有影响，Unity默认就是会帮你将C#代码给生成DLL。如果打包到Android或者iOS，现在都会再将DLL用IL2CPP转成CPP代码。 感谢liu@UWA问答社区提供了回答 A2：现在Unity各平台基本都是用IL2CPP，使用IL2CPP开始构建时，Unity会自动执行以下步骤： 将Unity Scripting API代码编译为常规 .NET DLL（托管程序集）。 应用托管字节码剥离。此步骤可显著减小构建的游戏大小。 将所有托管程序集转换为标准C++代码。 使用本机平台编译器编译生成的C++代码和IL2CPP的运行时部分。 将代码链接到可执行文件或DLL，具体取决于目标平台。 以上摘自Unity官方文档，以便题主理解。 IL2CPP官方文档：https://docs.unity.cn/cn/current/Manual/IL2CPP.html 感谢郑骁@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/620513ea34a9f84e39fb3fe4 AssetBundle Q：Unity 2020.3.16预制物嵌套时，子预制物引用的图片AssetBundleName修改后，母预制物会丢失引用。 举例来说，预制物A中有个预制物B，然后预制物B上的RawImage引用图片C。ABC三个打到不同AssetBundle中。 首次打包，加载全部AssetBundle，实例化A，A显示正常。 修改图片C包名，再次打包，A所在包不会有变动。但是加载全部AssetBundle，实例化A，A会丢失C的引用。 反编译AssetBundle会发现，实际预制物A所在资源包数据中有图片C的引用数据，但是因为二次打包A包无变化，就没有更新C所在包的数据。 这个问题升级Unity是否可以解决？或者在当前版本是否可以避开？ 反编译AssetBundle会发现A所在Bundle会直接以External References形式关联到图片C的地址，并且AssetBundle也会依赖到图片C所在Bundle（但是不依赖到嵌套Prefab B所在Bundle）。 Prefab B重新关联图片D再打包，A引用会正常刷新。但是仅仅修改图片C的BundleName再打包，不会触发A重新打包。 AssetBundle的Manifest显示的A和B依赖关系是不正确的，显示还是A依赖B，B依赖C，和实际解包出来的不一样。 现在已经用追踪Prefab嵌套树，外加资源BundleName监视的流程暂时解决了打包问题。但是还是希望能获得更规范的解决方案。 A：Unity Prefab嵌套目前只处理了Editor部分，打包AssetBundle时，会将Subprefab的序列化文件部分copy一份到Rootprefab，其实就等于AssetBundle环境下，嵌套Prefab不生效。 感谢郑骁@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6205139034a9f84e39fb3f6b AssetBundle Q：如下图所示，在报告中常注意到资源管理模块中AB.LoadFromFile单次调用耗时较高（几十甚至几百毫秒），且不同AssetBundle包加载耗时差距较大，请问是什么原因导致的？ A：理论上，当使用LZ4压缩的AssetBundle包加载时只需要加载头文件，不应该需要如此大量的耗时。猜测是使用了LZMA的打包方式导致的。 实验将10张、50张纹理分别用LZMA、LZ4打包，多次测试取中位数，得到AssetBundle加载耗时如下图，基本符合预测。 其中，LZMA加载AssetBundle需要同时进行解压，耗时与AssetBundle中资源大小相关（如图1，正好成5倍关系）；所以会产生报告中不同AssetBundle包加载耗时差距较大的现象。 而LZ4加载仅需加载头文件，耗时极低。 LZMA打包方式 LZ4打包方式 感谢Faust@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/62131191e7172c2775f36769 Shader Q：如何在发布APK的时候，利用代码自动剔除掉Shader中某一些Pass？希望这些Pass在Editor环境下可以使用，而在APK包中关闭，这样可以减少变体构建时间。 A：通过ShaderSnippetData提供的PassName匹配想要剔除的PassName就可以了。 感谢题主墙外行人@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/620a4af334a9f84e39023111 封面图来源于网络 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：793972859（原群已满员）
1）背包优化问题 ​2）Unity 2019在华为手机上2倍抗锯齿不生效 3）关于libunity.sym.so符号表的问题 4）Navmesh合并成一个新的NavMesh的方法 5）Prefab挂自己写的管理器脚本却无法打包 这是第260篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） UGUI Q：经常会有人问背包卡顿的原因分析，那到底是有多少种卡顿的原因以及优化的方式呢？ A1：推荐先看一下官方的UGUI课程：《Unity UI模块优化案例精讲》 对于没有优化过的背包，最大的消耗在于物品的销毁与实例化。 感谢潜行医生-577493@UWA问答社区提供了回答 A2：以下是我想到的一些点，期待其他大神补充更多的内容。项目中实际遇到的具体问题还需要具体分析，通过性能工具进行定位消耗过高的地方，然后有针对性地进行合理优化。 1.对于未优化的背包，列表滚动过程中，Cell的加载和销毁会造成卡顿。 解决办法：使用无限滚动列表Tableview这种控件，使Cell可以进行复用，避免物体的频繁实例化和销毁。 2.背包打开一瞬间，加载了很多个格子物品进来，造成卡顿和内存冲高，GC等问题。 解决办法：分帧加载，控制一帧实例化的Cell个数，避免在同一帧内大量创建格子物品。针对资源Load过程中的卡顿，可以采用提前预加载资源到内存的方式。 3.背包刷新时卡顿，大量的格子监听某个事件，刷新时可能造成卡顿。 解决办法：用脏标志的方式去刷新，不该刷新的部分不刷新。 4.Cell上的图片，粒子特效显示等设计不合理造成DrawCall过高。 解决办法：这个需要结合具体的项目和设计方案进行分析和优化。 感谢马三小伙儿@UWA问答社区提供了回答 A3：推荐一下FairyGUI这套UI系统，FairyGUI的List只要SetVirtual就行了：https://www.fairygui.com/docs/editor/list 感谢萧小俊@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60f64c3694846f188daa35d8 Rendering Q：Unity 2019上，工程同时使用PostProcessing后处理功能加上抗锯齿，在华为手机上2倍抗锯齿是没效果的。 开启后处理+抗锯齿在手机上的效果图： 关闭后处理+抗锯齿在手机上的效果图： A：测试机型荣耀Play 4T在开启后处理的情况下，2x MSAA不会生效，但是4x和8x会生效。 使用Graphics Analyzer分析真机上的gl调用发现，MSAA生效需要在场景加载前调用 glFramebufferTexture2DMultisampleEXT接口，但是在开启后处理功能并且设置为2x MSAA的情况下，引擎调用的却是glFramebufferTexture2D接口，导致抗锯齿在场景中没有生效。 但是测试小米8和Oppo A32在开启后处理的情况下设置为2x MSAA并且生效。猜测是引擎方面针对不同的GPU硬件做了一些设置，现在只能在性能允许的情况下尝试开启4x MSAA来达到抗锯齿效果。 附件（可戳原问答下载）中有两个测试APK包和一些真机测试结果。荣耀Play 4T上不开启后处理的情况下，单纯的2x MSAA和4x效果几乎一模一样。 感谢宗卉轩@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60ef9a9794846f188da13d40 Android Q：项目采用的是IL2CPP模式打包，选取arm64-v8a和armeabi-v7a两个版本，没有开启Strip Engine Code选项，Unity打包版本是2018.3.6f1 现在线上的包有ANR报错如下： #00 pc 000000000004b7cc /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) #00 pc 000000000004f680 /apex/com.android.runtime/lib64/bionic/libc.so (__futex_wait_ex(void volatile*, bool, int, bool, timespec const*)+144) #00 pc 00000000000b2120 /apex/com.android.runtime/lib64/bionic/libc.so (NonPI::MutexLockWithTimeout(pthread_mutex_internal_t*, bool, timespec const*)+688) #00 pc 00000000009fe7b4 /data/app/~~AxXJ-H5OqAWLfQK2almqqg==/com.saiyun.avgchapters.episodestories.romance-HeZPf9aJrCJYoKrQ20DOrg==/lib/arm64/libunity.so (???) #00 pc 00000000009fe778 /data/app/~~AxXJ-H5OqAWLfQK2almqqg==/com.saiyun.avgchapters.episodestories.romance-HeZPf9aJrCJYoKrQ20DOrg==/lib/arm64/libunity.so (???) #00 pc 0000000000508938 /data/app/~~AxXJ-H5OqAWLfQK2almqqg==/com.saiyun.avgchapters.episodestories.romance-HeZPf9aJrCJYoKrQ20DOrg==/lib/arm64/libunity.so (???) #00 pc 0000000000347f1c /data/app/~~AxXJ-H5OqAWLfQK2almqqg==/com.saiyun.avgchapters.episodestories.romance-HeZPf9aJrCJYoKrQ20DOrg==/lib/arm64/libunity.so (???) #00 pc 00000000006e3638 /data/app/~~AxXJ-H5OqAWLfQK2almqqg==/com.saiyun.avgchapters.episodestories.romance-HeZPf9aJrCJYoKrQ20DOrg==/lib/arm64/libunity.so (???) at com.unity3d.player.UnityPlayer.nativeInjectEvent (Native method) at com.unity3d.player.UnityPlayer.injectEvent (unavailable) at com.unity3d.player.UnityPlayer.onTouchEvent (unavailable) at android.view.View.dispatchTouchEvent (View.java:15199) at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3914) at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3578) 查看报错的机型Samsung Galaxy S10，使用的是arm64运行的游戏，我尝试使用PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Symbols\arm64-v8a下的libunity.sym.so文件查找函数名，但是提示找不到方法。 这是什么原因？我需要用哪个符号表才能查找函数名呢？ A：建议你试试toolchains/x86_64-4.9/prebuilt/darwin-x86_64/bin/x86_64-linux-android-addr2line这个路径。 感谢Lim@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60f6866a94846f188daa889f NavMesh Q：这边有一个需求，将一张很大的地图分割成若干小块，目的是为了方便美术操作，然后将单个小块地图烘焙生成NavMesh。Unity提供的NavMeshLink要配点，不方便操作。请问还有其他思路去操作嘛？ A：我觉得，Unity的原生系统给的API还是太少了，你可以试下这个插件 A* Pathfinding Project Pro，它是一个C#版本的完整RecastNavigation实现，还包含传统的Grid寻路，你可以控制的更多；至于这个动态的NavMesh，你可以考虑试试 TileMesh，具体可以查看RecastDemo中的TileMesh，可以逐个Tile的按需创建。 感谢Yaukey@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5c988c0e276f530b35fdd967 Build Q：各位有没有碰到过在场景中的一个Prefab挂了一个自己写的管理器脚本，然后打包打不进去的情况：script asset xx.cs can not be include in assetbundle A：检查一下这个CS文件中是否有包含Editor的代码，或者Define Symbols导致Unity无法识别你的Core。 感谢萧小俊@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60f0383594846f188da22360 20210726 更多精彩问题等你回答～ 1.Vulkan与OpenGL的选择是否会对内存大小产生影响 2.关于Unity出AAB包的问题 3.RTS 手游技术难点 封面图来源于：Inventory System Unity库存系统。 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：793972859（原群已满员）
1）HttpWebRequest下载大文件速度变低问题 ​2）Unity 2018.4.3X版本打AssetBundle慢 3）Unity 2D地图的动态修改 4）Unity 3D UGUI粒子特效裁剪的解决方案 5）Addressables LoadAssetAsync加载预设体的执行问题 这是第259篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Script Q：游戏使用HttpWebRequest进行内容更新，在Google Play只上传小包，打开后再下载资源。 正常下载速度在10MB左右，在使用4G的情况（Wifi下没出现过，4G基本必现）下下载大概10几秒会出现速度断崖式下降，达到10几KB乃至几KB。然后会卡在这个速度进行龟速下载，如果中断连接重新开始断线重连又会回到10MB的速度，基本下载完整资源需要如此反复2~3次。 下载资源放在腾讯云香港服务器，使用腾讯云的CDN加速服务。版本：Unity 2018.4.34。 A：可以检查下： Wifi下没有出现过问题而4G上出现问题，需要先排查一下是不是运营商的问题，电信移动联通都试一下。 可以检查一下CDN的状态，CDN的后台应该可以看到2XX、3XX、4XX或5XX出现的次数 ，排除某文件本身存在的问题或者CDN网络不稳定。 考虑下载一个文件，分多个Range段，多线程下载。 可以参考一下UWA学堂的文章《手游HTTP多线程下载原理与优化》，这篇文章写得不错，解决了很多热更新的资源的痛点。 感谢萧小俊@UWA问答社区提供了回答 Build Q：Unity 2018.4.3X版本打AssetBundle慢，同样的电脑环境下，已经换过2018.4.36f1、32f1、20f1和34f1版本，但用之前的2018.4.1f1版本打AssetBundle就飞快。 已经把各种资源都试了一波，Unity和工程都放在C盘，都是固态环境，电脑i7-10700，老版本2018.4.1f1飞快，2w资源增量一次3分钟，从头开始打得20分钟左右，然后新版本从头打得10小时+，不知道那个地方我有疏忽，已经来回把工程导入了好几次。 A1：介绍几个分析方法: 看Editor.log能看到Unity大概正在做什么； 用Procexp、Process Hacker之类的工具，配置好符号PDB路径，可以看Unity主线程的栈，多刷新几次，能猜到大概在做什么； 用VS附加一个性能分析器到Unity进程，抓几分钟，能看到热点调用栈。 感谢littlesome@UWA问答社区提供了回答 A2：楼主看看这个帖子有没有帮助，也是前不久出现在问答区里面的： https://answer.uwa4d.com/question/60d3ee2de58b4719dd3e26cd 感谢马三小伙儿@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60f27a5f94846f188da51f71 Rendering Q：斗斗堂炮弹轰击后地表塌陷如何实现？ A：给对应的场景图片生成一个Mesh，之后打到的时候去更新那个网格即可。 UnityStore上有一个不错的插件可以看一下： https://assetstore.unity.com/packages/tools/sprite-management/destructible-2d-18125 也可以看一下Poly的算法： https://blog.csdn.net/6346289/article/details/105760374 感谢萧小俊@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60ebf8c694846f188d9c5fcc UGUI Q：请问UGUI粒子特效的裁剪有哪些比较好的解决方案？比如Sprite Mask要设置缩放，感觉使用起来有些不方便，比如用Shader如何裁剪？ A1：可以参考一下这个： https://www.programmersought.com/article/7682124522/ 感谢羽飞@UWA问答社区提供了回答 A2：可以参考一下这个： https://blog.csdn.net/akak2010110/article/details/81293913 感谢super@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60d7d828e58b4719dd3e27f3 Addressable Q：我在项目中使用Addressables.LoadAssetAsync加载预设体，然后实例化，在我加载完毕实例化之前就会执行预设体挂载的脚本。如果我再实例化预设体，则会执行两遍脚本。请问这块正确的做法是怎么样的呢？ A1：这个是1.18加了同步加载出现的问题，版本降回1.17.17就好了。 感谢唐@UWA问答社区提供了回答 A2：发现下面一个帖子，确实是版本的问题，我现在升级到1.18.11，目前没有遇到这个问题了。 https://forum.unity.com/threads/assetreference-instantiateasync-on-addressables-1-18-calls-awake-onenable-and-ondestroy-twice.1109402/ 感谢题主BreakJail@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60f0039a94846f188da1d97f 20210719 更多精彩问题等你回答～ 1.Vulkan与OpenGL的选择是否会对内存大小产生影响 2.关于Unity出AAB包的问题 3.RTS 手游技术难点 封面图来源于网络 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：793972859（原群已满员）
如何管理大型游戏的美术资源工程
1）如何管理大型游戏的美术资源工程 ​2）Google Play强制64位App相关问题 3）零散AssetBundle资源再打包疑问 4）Unity中Api Compatibility Level .net 4.x与.NET Standard 2.0的区别 5）Unity 2020版本OpenGL ES3下SRP Batcher失效问题 这是第252篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Assets Q：随着项目参与制作的人数变多，各类美术资源的数量也在急速上升，纵然有各种规范和各类资源导入、检查工具，跑一段时间后，仍然会出现工程里各类废弃的资源未能及时清理，导致资源和包体大小持续上升，包括： 1）各类资源在制作过程中产生的一些中间文件； 2）原本在使用，但后面随业务需求变动，已弃用的资源； 3）原本就属于要放到游戏中看看效果，但没实际投放的资源。 想问下大家在处理这类问题时的一些方案？ A1：题主遇到的问题和技术无关，和流程有关。 （1）监管工作负责到人，凡事预则立、不预则废 每个项目都需要有一个Performance Owner来对性能、资源等问题进行管控。如果没有这个人，再强大的工具、再NB的团队也是白扯。这个人可以是项目的制作人、主程、QA Leader或者PM（一般小团队不具备）都可以，就我们合作的团队来看，以QA Leader作为Performance Owner的团队居多。 （2）监管流程要跟上 团队中必须要有人来对资源问题、性能问题进行负责，且制定固定的流程来强制团队养成持续监控、持续完善的习惯。三天打鱼、两天晒网的形式，是很难成事的，做游戏开发也是如此。所以，将监控变成团队研发的习惯，就需要通过流程来不断把控，流程做到位了，一切就都好了。 以上两点做到了，题主的问题自然就解决了。 该回答由UWA提供 A2：监管负责人一般是PM。因为有些QA没有常识，也没有权利，PM最好懂业务，如果没有PM最好就给客户端主程这个权利，锁版本是很必要的，大部分大厂都有这个。 用工具限制美术的操作，所有不正确的全部报错，然后提示清楚。用锁版本限制提交节点。然后要求不守规矩的人离开，不要问为什么会报错。当然必须从制作人开始就要支持。通俗地讲，美术和策划不会操作工具又不肯学习的，不配合作。 感谢马古斯@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60ab197f6bb31032f979184e Build Q：Unity可以通过程序集加载对应的代码，且Google Play已经强制64位APP，是否已经不支持通过Assembly.Load加载代码了？ A：如下图所示，Unity里面Mono版本还不支持ARM64，所以要上Google Play（64位要求）只能使用IL2CPP，IL2CPP是不支持Assembly.Load的。 可以参考： https://forum.unity.com/threads/il2cpp-loading-c-assembly-at-runtime.417553/ 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60ae09c06bb31032f97918c7 AssetBundle Q：Unity的AssetBundle资源有必要把零散的AssetBundle资源做成Zip吗？比如300MB一个。因为在打AssetBundle的时候可以选择压缩格式，所以不是为了减少总体的大小，而是如果散的AssetBundle，在下载的时候性能会不会有压力？各位在实践中都是怎么处理的呢？（资源量AssetBundle数量10W+，总大小在4G左右。） A1：一堆散文件下载自然不如一个大文件更快，Http连接也要时间和资源，有时候AssetBundle其实只有几KB。不划算。打Zip算比较方便，可以考虑不带压缩打Zip。当然也可以自定义格式来做，但是合大文件以后更新会麻烦点，要做一些管理和替换。 感谢黄程@UWA问答社区提供了回答 A2：最近刚好做这个功能。将多个包打成Zip，对下载效率有很大的帮助，特别在国外网络环境下。 1.AssetBundle打包依旧是零散的AssetBundle包（AssetBundle会做模块区分，比如特效、UI等）。 2.需要热更新时候，生成的AssetBundle包信息和上个版本AssetBundle包对比，将各个模块变动的AssetBundle包生成Zip包。 3.热更新的时候，收集需要更新AssetBundle信息（有标记Zip，说明资源在Zip包里）进行下载，没有标记Zip，则直接下载AssetBundle包，这样兼容跨多个版本热更新功能。 4.下载完的Zip包在客户端在解压成AssetBundle。 感谢杨宇杰@UWA问答社区提供了回答 A3：当个搬运工补充一个回答： 散列的坏处比较集中：下载慢（用cdn，oss后端性能不必考虑），上传到oss也是慢得多。 Zip无论跳包管理，下载冗余，都是很头疼的事情，做动态下载更加不可能。因此可能导致比散列更加昂贵的oss成本。 感谢芭妮妮@UWA问答社区提供了回答 A4：前期开发用零散文件，文件小也省掉了断网续传的问题，后期时间富裕了再扩展为大包的方式，可以根据版本号生成增量更新包一次下载完成。 放服务器上没什么影响，定期清理一下。 感谢rekcah1986@UWA问答社区提供了回答 A5：上一个项目用的Zip打包，运营时间长了以后，冗余资源会越来越多。热更资源要保证完整性不能删，除非你们是换包了，如果你们频繁换包，那么用Zip的方式是最合适的。 感谢Lim@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60ab59946bb31032f9791856 Editor Q：Unity中Api Compatibility Level .NET 4.x与.NET Standard 2.0的区别是什么呢？ A：.NET Standard 2.0对平台的支持性更广、兼容性更好。.NET Standard 2.0的API是.NET 4.x的子集。或者说，.NET 4.x支持的API更多一些，兼容.NET Standard 2.0，但是有些API在有些平台上是不兼容的。 Unity默认选择的是.NET Standard 2.0，如果想要跨平台兼容，那么就选Standard 2.0。如果使用的外部类库或者脚本里面调用的API不被Standard 2.0支持，再考虑换成4.x来试试。 以官方文档为准： https://docs.unity3d.com/Manual/dotnetProfileSupport.html 感谢Prin@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60a31c676bb31032f9791730 Rendering Q：在Unity 2020版本下，OpenGL ES3下SRP Batcher失效，查看lit.shader显示不兼容SRP，该怎么解决呢？ A：经排查，在Unity 2020.2的某些版本下并没有出现上述问题，但后续的版本就坏了。现在看到2020.3.9f1的Release notes里有提到这个问题。 可参考此处。 感谢小ben@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60adc07e6bb31032f97918b1 封面图来源于网络 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：793972859（原群已满员）
1）ShaderLab占用疑问 ​2）关于Android下ARM64和ARMV7的问题 3）关于ILRuntime相关的性能检测工具 4）字体加载问题 5）LZ4压缩模式下的资源打包 这是第239篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Shader Q：我从官网下载了一份内置Shader，自己写工具刷了一遍，确认界面里面材质球已经没有引用内置Shader，并且把Standard Shader都清除了，从内存去看也没有这个，但是ShaderLab的占用还是有点大，现在在主场景有47MB。 A1：变体太多就会这样，仔细看看那些很多关键字的Shader。 感谢deviljz@UWA问答社区提供了回答 A2：楼上说的对，分享一段几年前写的扫描工程Shader变体的代码，扫描一下，把Top前几的Shader改改就能降很多了。 [MenuItem("Find/GetAllShaderVariantCount", false, 20)] public static void GetAllShaderVariantCount() { #if UNITY_5_6 Assembly asm = Assembly.LoadFile(@"D:\Program Files\Unity_5.6.5f1\Editor\Data\Managed\UnityEditor.dll"); System.Type t2 = asm.GetType("UnityEditor.ShaderUtil"); MethodInfo method = t2.GetMethod("GetComboCount", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); #elif UNITY_2017_1_OR_NEWER Assembly asm = Assembly.LoadFile(@"D:\Program Files\Unity_2018.3.0f2\Editor\Data\Managed\UnityEditor.dll"); System.Type t2 = asm.GetType("UnityEditor.ShaderUtil"); MethodInfo method = t2.GetMethod("GetVariantCount", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); #endif var shaderList = AssetDatabase.FindAssets("t:Shader"); var output = System.Environment.GetFolderPath(System.Environment.SpecialFolder.DesktopDirectory); string pathF = string.Format("{0}/ShaderVariantCount.csv", output); FileStream fs = new FileStream(pathF, FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fs, Encoding.UTF8); EditorUtility.DisplayProgressBar("写统计文件", "正在写入统计文件中...", 0f); int ix = 0; sw.WriteLine("ShaderFile,VariantCount"); foreach (var i in shaderList) { EditorUtility.DisplayProgressBar("写统计文件", "正在写入统计文件中...", 1f * ix / shaderList.Length); var path = AssetDatabase.GUIDToAssetPath(i); Shader s = (Shader)AssetDatabase.LoadAssetAtPath(path,typeof(Shader)); var variantCount = method.Invoke(null,new System.Object[]{ s,true}); sw.WriteLine(path + ","+variantCount.ToString()); ++ix; } EditorUtility.ClearProgressBar(); //清除进度条 sw.Close(); fs.Close(); } 感谢李星@UWA问答社区提供了回答 A3：URP有一套变体裁剪代码，拿来改改，加入你的打包流程会裁剪掉没用的变体（我估计你很多关键字用不到，所以应该会减不少）。 感谢Robot.Huang@UWA问答社区提供了回答 A4：推荐使用UWA的本地资源检测，看下哪个Shader的变体多，是不是变体的问题，另外再确认一下是不是还有Shader的冗余。 感谢芭妮妮@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/603070d1cfa35d5b53669567 Build Q：关于Android下ARM64和ARMV7的问题，从经验上讲，同一个Unity的游戏在这两个架构下会出现运行效率的差异吗？渲染效率会受到CPU架构的影响吗？ A：ARM64能解决很多因地址空间不足、内存分配时出现地址冲突而导致的内存分配失败的问题。比较典型的就是高通的Adreno显存不足，或者说字典这种容器类型大量使用导致的内存泄露问题。但是，伴随着的问题也就来了，同样的包64位比32位要大，对于对内存有严格要求的游戏，本来优化内存就已经够头疼了，换成64位突然又涨了一截，一股苍白无力感又油然而生。至于效率问题，没测试过也没对比过，楼主可以测测FPS、温度、能耗等有多大区别。 感谢李星@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6018e4fa10a17c6c2b09de08 ILRuntime Q：UWA已经出了针对Lua的性能分析，求ILRuntime，新项目打算改用ILRuntime，看中Await和Async来实现网络通讯的“同步”代码，战斗部分的逻辑代码也打算在ILRuntime中实现（强CPU计算会尽量用C#实现），但是性能方面略有担心。若有性能分析工具特别是与C#相互交互部分，可以在初期定技术框架给自己一颗定心丸就好了。 另外，请问ILRuntime已经有哪些项目在线上成功应用吗？再就是稳定性方面能接过Lua的拉力棒担当重任吗？ A1：基本满足日常需要。其实底层机制还是与Lua类似的，开发习惯和语言上会舒服不少。作为功能模块附加或者热更新功能还是很不错的。不过性能方面没有非常针对性地去做测试，目前只能说满足项目需要。高计算量处理方面还是不建议在ILRuntime做太多，基础原因其实跟Lua问题还是蛮类似的。 使用上来说，要注意Adaptor的定义。还有热更新方面，不同代码节点可能是需要分别出ILRuntime的热更包。这个在出包管理上会烦琐一些，不过开发语言统一上还是有不少好处的。 感谢阿里@UWA问答社区提供了回答 A2：性能方面其实不需要太大的担心，分享一下我的经验： 一定要用Release方式去编译DLL，并且打开DISABLE_ILRUNTIME_DEBUG的宏； 由于解译执行，所以执行效率跟直接执行天然就有20-100倍的差距，太复杂的计算肯定不行； 运行时也是纯C#的，所以用UWA工具就能检测出一些性能问题； 我们项目安卓用的有原生DLL效率肯定是比Lua要快的，iOS上面测试下来比Lua要慢一点，但是苹果设备以及IL2CPP的性能都不错，所以也能做到跑满帧； 对对象中的结构体赋值会有无法避免的GC，建议先转成本地变量，或者V3这种直接存成XYZ； Foreach会产生GC，写的时候不要用。 感谢萧小俊@UWA问答社区提供了回答 A3：知识搬运工芭妮现身，搬于某国内新一线大厂的大柴： 有朋友用这个做上线了还行，计算密集型不能胜任，计算密集型可以用Lua，双热更核心也是个值得参考的点子。 核心代码用C#，例如：物理系统模拟之于闪暖。 战斗库逻辑层用Lua，例如：秒算战报的回合制的战斗核。 业务逻辑用ILRuntime，例如：装备系统，升阶升星强化转生。 再套一层Injectfix，修非Burst的C#。 感谢芭妮妮@UWA问答社区提供了回答 A4：因为ILRuntime是C#实现的，所以直接看Profiler就能看性能消耗。 感谢终极大菜狗@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5c330dc89efb1b001255ddd9 Resource Q：我现在真机测试，在内存发现有两份字体的加载，一份是比如登录界面，或者其他本身有字体的场景引用到的，引用的是原始的Font，另一份我发现是因为预制体加载到场景，会引用一份复制出来的字体。这个要怎么解决？ A：如果预设体是从AssetBundle中加载的，场景却不是AssetBundle加载的，那么肯定是会有两份的，因为普通的场景打包和AssetBundle走的是不同的路线，是引用不到同一份字体资源的，一份是来自场景的Sharedassets，一份是来自AssetBundle。所以要么场景也走AssetBundle打包，要么场景中的用到这个字体的UI部分从AssetBundle动态加载。 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60307011cfa35d5b53669566 Addressable Q：LZ4压缩模式下，Addressables加载Bundle只会加载Headers到内存中，那么是否可以将所有资源打包成一个Bundle？这样就可以不用考虑资源粒度以及资源重复打包的问题了？ A1：如果是文件级别的资源更新，并且AssetBundle很大的情况下和重新下载整包没什么太大区别，资源粒度主要是为了方便减少更新资源量。 感谢郑骁@UWA问答社区提供了回答 A2：说一下我的整体思路，请大佬看看有没有什么隐患。 所有资源使用Addressable打成一个Bundle包，固定读取路径为UnityEngine.Application.persistentDataPath，即永远读取本地。舍弃边玩边下这个模式，实际体验起来，边玩边下会导致频繁的卡顿，体验很不好。 首包发布一个小包，游戏启动时检查资源更新，资源Bundle（包括后续的增量包）通过C#的HttpWebRequest下载（自己管理下载），支持断点续传，统一下载到persistentDataPath，下载完成后正式进入游戏流程。 优点： 资源管理简单。 不用考虑资源拆分粒度。 不用考虑资源重复打包。 不用考虑首次启动下载太多Bundle包导致的下载速度缓慢的问题。 缺点： 目前没想到有什么隐患，请大家帮忙指正。 感谢题主ShiltonLi@UWA问答社区提供了回答 A3：从资源卸载的角度来说这样做是不太合理的。Addressable是通引用计数来处理卸载的，只有当AssetBundle的引用计数减少到0的时候才会触发，触发时会调用AssetBundle.Unload(true)。所以如果这个大的AssetBundle里面有一个资源需要一直常驻内存，就说明那个AssetBundle也需要常驻内存，那么其它用不到的资源，如某张短时间使用过后就可以卸载的纹理，就卸载不掉了。当然这个说法的前提是用Addressable的加载接口和卸载接口来加载卸载资源。 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/602e41adcfa35d5b53669517 封面图来源：Unity Shader Sketches https://lab.uwa4d.com/lab/5b564b46d7f10a201fd903de 使用ShaderLab绘制草图。 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：793972859（原群已满员）
1）运用Post Processing导致帧率明显下降 ​2）RectMask2D是不是会频繁触发SendWillRenderCanvases 3）Unity3D Sence为何一直处于已修改状态 4）Sprite Atlas打Bundle的冗余问题 5）IL2CPP在Xcode下增量编译问题 这是第220篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Rendering Q：项目中运用了Post Processing后，帧率下降巨大。测试场景，模型面数2w，普通的Diffuse材质 ，没有物理，没有特效。没开后处理时，低端机30帧。开启后处理，帧率抖动，最低达到15帧。后面只用到Bloom和Color Grading。 A：如果Bloom用的不好，GPU性能耗时高是较为正常的事情。Bloom的上下采样次数、Filter滤波的Sample点个数、屏幕的分辨率等都是影响Bloom性能的重要因素。 建议题主可以考虑阅读《Unity引擎景深实现原理剖析与优化》这篇技术课程，里面优化DOF的方法依然可以用到Bloom上。 同时，也可以使用GOT Online中的Overview模式，直接查看项目在真机上（最好是高通芯片）的GPU耗时，看看GPU的具体超标情况： 该回答由UWA提供，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5f637e119424416784ef2348 UGUI Q：RectMask2D是不是会频繁触发SendWillRenderCanvases？ A：是的，Rect Mask 2D会持续每帧计算子节点的裁剪区域。所以Rect Mask 2D下面的元素如果比较多，耗时还是挺高的，这种情况可以换成Mask组件，虽然Mask的Overdraw会高一些。一个省GPU，一个省CPU，两个是需要权衡的。 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5f6446d19424416784ef23af Editor Q：Unity 3D Sence一直处于已修改状态。刚切换过来也直接提示已修改。切换Sence并未作出任何修改，如下图： 虽然没什么难题，但切换别的场景或者退出的时候就要提示让保存了。 之前发现的一个原因是因为UI中存在套用的Layout组件呈警告状态。修改后Sence就恢复正常了。各位有遇到过这种问题吗？ A：所以说还是嵌套了Layout组件。这个会导致Sence一直处于修改状态。 感谢刘旭杰@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5f62cba59424416784ef2321 AssetBundle Q：游戏中UI用Sprite Atlas做合图，打Bundle貌似碰到了一个冗余问题：（Unity 2019.4.1 lts版本）。 Victory目录有四张散图，以及一个Sprite Atlas文件做合图。Bundle时把整个Victory为一个Bundle。最终出来的Bundle结构如下： 也在网上搜了一些信息，尝试去掉Sprite Atlas的Include in build选项（效果未验证，纯粹验证Bundle），Bundle中少了一份冗余的Texture 2D，但依旧有几个Sprite类型的散图。 疑问： 我理解是，Bundle中已经有一个sactx-1024x2048的合图了，为什么还有Sprite类型的散图？这是否算冗余呢？ 用去掉Include in build的方式，游戏中使用UI Prefab时，是否都需要用Late Binding才能使用图片（感觉很麻烦，UI拼每个界面，都要程序写配套代码）？ A1：最开始描述的问题中（根据第一张截图）并未看到冗余的存在，也并非图集形式的打包结果。 回答如下： 对于图集本身的Bundle肯定是不算的，需要有各个散图的信息才能从整图中获取散图，不然就不知道你要的那个图在哪里。 不勾选Include in build，Bundle中就不会存在显式的图集依赖，必须使用延迟绑定传递信息（该图片从哪个图集中获取）给请求图片资源的对象。 感谢Welkin_Totoro@UWA问答社区提供了回答 A2：描述下我的思路： 勾选了Include in build，Bundle中就会有一份冗余：既包含合图，又包含散图。但这种情况下，程序不需要做特殊逻辑，界面就能表现正常（具体Runtime是否合图，未抓帧验证）。 不勾选Include in build（正确做法）：Bundle就会只包含Atlas，以及散图信息（不是完整的散图）。游戏内使用Atlas Request Manager来确保图片能正常显示，否则会错乱。如果自己实现了资源加载的话，可能还要自己找时机做Atlas资源卸载。 感谢james@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5f5f15739424416784ef22f8 Build Q：最近在研究加速打包问题，发现IL2CPP生成代码之后每次Xcode都是全量编译（直接Build而不是Clean+Archive）。 我参考这里看了下， https://forum.unity.com/threads/incremental-builds-for-il2cpp.365470/， 对比了下如果C#代码没有变化，生成的CPP代码的内容确实不变。但是重新生成貌似会导致文件修改时间变化或别的属性变化，Xcode依然是所有都编译了一遍。 A1：目前准备用群里大佬说的方法绕开： “Freshair 17:01:28 打出的Xcode用SVN同步到Xcode打包项目下” 我用Dnspy看了下IL2CPP.exe直接修改代价有点大，而且不好维护。用BeyondCompare比较了下发现其实就Preprocessor.h和Native文件夹俩修改时间产生了变化。希望以后官方能注意这些细节。 感谢钱康来@UWA问答社区提供了回答 A2：介绍一篇文章《Unity Xcode构建缓存》，里面写了一个程序解决Unity生成Xcode项目缓存问题。 WriteCache使用Rsync增量传输，会节省时间，ReadCache未做优化，实测用时37秒左右，1.5GiB大小Xcode项目——UnityXcodeCache 感谢狂飙@UWA问答社区提供了回答 A3：我之前的做法是细化打包策略，资源打包细分为差不多10个步骤，对UI，特效，Lua（分三块，Core，模块，Luatable配置），C#层Config，角色，场景，编译工程，资源覆盖，快速编译，生成APK/IPA，云真机测试，组织成不同的打包命令提供给CI。 如果是C#代码没变化，可以只做资源类的打包，对需要重新（此处可增量）打包的AssetBundle，Lua，Config等打包，打包后直接覆盖到Xcode工程，直接生成IPA包，跳过中间环节，构建过程可以细化到很细，如果你是Lua侧，那估计只需要打包Lua模块相关，1分钟内就可以出到IPA包。 如果是Xcode代码也发生变化，这个可以结合Ccache进行提速，资源打包可以做分布式打包，多台黑苹果去打包各个模块的资源。再传递到版本机上整合，这个过程也可以hook svn/git的资源提交，在提交后做一次打包，再次发布的时候可以增量处理。 其实可以脱离AssetBundle，把量产资源采用非AssetBundle的方式进行组织。避开不必要的导入导出及打包。 感谢debugger@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5b90ebbb670c1a61c64d6cd3 封面图来源于网络 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：793972859（原群已满员）