乐趣区

关于animation:关于Addressable打包图集与图片都打进去造成冗余

1)对于 Addressable 打包图集与图片都打进去造成冗余
​2)Unity 如何计算 Root 动画旋转
3)IL2CPP 编译的 Protobuf 反射类运行时报空
4)为什么 Active Constraints 会呈现过高的景象


这是第 337 篇 UWA 技术常识分享的推送,精选了 UWA 社区的热门话题,涵盖了 UWA 问答、社区帖子等技术知识点,助力大家更全面地把握和学习。

UWA 社区主页:community.uwa4d.com
UWA QQ 群:465082844

Addressable

Q:对于 Addressable 打包图集与图片都打进去造成冗余。

Unity 版本:2021.2.13f1c1
Addressable 版本:1.19.16(cn 版本)

应用的是 Addressable 的默认 Group,场景中只应用了 decal3 的 UI 图片,然而打包最初的资源,Addressable 的包中蕴含了两个资源,失常应该只有图集资源才对(如下图)。

另外,看了 Addressable 打包流程的代码,Unity 把关联的图片退出依赖打包列表,然而又在之后对图片检测做了生成图集的解决。原生打包不会对图集里的图片再做解决吗?

A:能够切换 com.unity.ScriptableBuildPipeline 版本到 1.21.5 试试看,1.21.5 修复的问题应该包含这个。
更新日志:
https://docs.unity3d.com/Packages/com.unity.scriptablebuildpi…

感激 liuxianfeng@UWA 问答社区提供了答复

Animation

Q:想理解 Unity 的 RootMotion 的实现细节,请问 Unity 是怎么计算 Root 动画旋转的?

一个动画,如果配置正确,AnimationClip 里会多两段曲线数据,RootT、RootQ 别离是根节点的位移和旋转信息。然而当我用 Animator 跑起来后,咱们每帧 RootMotion 旋转多少,Root 节点逆向旋转多少,是怎么计算出来的呢?

奢侈的想法是:旋转以后帧的 RootQ 绝对于第 0 帧 RootQ 的旋转的 eulerAngles.y。然而通过我屡次测试,并不是这个值,而是有偏差的一个值。有时候多几度,有时候少几度。

没有 Unity 源码的状况下,很难晓得它的计算方法。我去看了 Godot,其办法是失常把以后旋转和第 0 帧做差值。

比方这个动画,我曾经把数据删得差不多了。第 1 帧,Animator 认为应该转 24.068,这两个旋转的欧拉角示意别离是(277.77, 66.96, 81.36)、(279.53, 74.28, 100.03),from to 旋转的欧拉角是(3.29, 25.78, 0.02)。这个 25.78 和 24 差得不多,然而总归不一样。其余测试数据相似,都是差一点。

A:对于旋转的计算,Unity 应用了四元数(Quaternions)来示意旋转。旋转的差别可能是因为以下起因之一导致的:

  1. 欧拉角(Euler angles)转换为四元数的过程中可能存在精度损失。欧拉角存在万向锁问题和旋转程序问题,这可能导致从欧拉角转换为四元数时呈现不精确的后果。
  2. 根节点旋转的计算可能受到其余因素的影响,例如动画过程中的插值算法、关键帧的设置、平滑过渡等。这些因素可能会导致计算结果与冀望的差别。

感激 NG 週 @UWA 问答社区提供了答复

Script

Q:IL2CPP 编译的 Protobuf 反射类运行时报空,问题产生时,会闪崩,闪崩日志信息:
ErrorNotNull:”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

at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00000] in <00000000000000000000000000000000>:0 n

at System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic) [0x00000] in <00000000000000000000000000000000>:0 n

at Google.Protobuf.Reflection.ReflectionUtil.GetReflectionHelper (System.Type t1, System.Type t2) [0x00000] in <00000000000000000000000000000000>:0 n

at Google.Protobuf.Reflection.ReflectionUtil.CreateFuncIMessageObject (System.Reflection.MethodInfo method) [0x00000] in <00000000000000000000000000000000>:0 n

具体信息请见原网页。

看下来是因为 AOT 编译时代码剔除所致,问题十分偶现。咱们的 QA 基本上没有跑进去过这个问题,然而放到外网就有一堆玩家遇到此问题,蹊跷的是哪怕同一个手机也是偶尔才报。

Proto Github 我的项目有人提过:
https://github.com/protocolbuffers/protobuf/issues/5422

这个问题包含上面回复次要提了两点:
1. linker 蕴含 Google.Protobuf 程序集
2. AOT 编译器不会为 T、为 AnyEnum 的泛型办法,针对枚举参数泛型办法创立显式调用类 https://docs.unity3d.com/cn/current/Manual/ScriptingRestricti…

和我这个问题不同点是,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 序列化数据应该是惯例操作,置信应该有很多人遇到,不晓得大家解决计划是什么?

A:能够尝试以下办法:
Initialize the library and verify operation | Android Developers

Ahead-of-time compile (AOT)
Ahead-of-time compile is required for the IL2CPP backend and Unity versions 2017 and 2018 (but not for later versions of Unity).<br/>
The AOT compiler may not generate code for generic methods. You need to force the compiler to generate the proper code required for protobuf by adding the following method:<br/>

using Google.Protobuf.Reflection;
using UnityEngine.Scripting;

...

// Don't call this method.
[Preserve]
void ExampleOfForceReflectionInitializationForProtobuf()
{FileDescriptor.ForceReflectionInitialization<Scene>();
    FileDescriptor.ForceReflectionInitialization<ShadowType>();
    FileDescriptor.ForceReflectionInitialization<LevelType>();
    ...
    // Add FileDescriptor.ForceReflectionInitialization<T> for each generated enum.
    // You can find the list of enums in DevTuningfork.cs -> enum section
    // or in the list of enums in Google -> Android Performance Tuner.
}

感激 hanxu@UWA 问答社区提供了答复

Physics

Q:通过 Profiler 剖析我的项目,发现其中 Active Constraints 这一项会忽然呈现一个很不合理的峰值。目前只发现与角色身上是否挂载刚体无关。

然而与刚体数量比照起来,这种极高的 Active Constraints 为何会产生是毫无脉络的。在此向各位求教下。

A:从官网文档的截图里能够看到,在一个刚体的状况下,官网的实例里仍旧也会产生 17.29KB 的 Active Constraints。预计是统计形式有问题,又或者是了解上存在差别。

我在 Unity 2018 和 Unity 2020 这两个版本都见到过 Active Constraints 过高的景象。

至多目前来讲,这个数量级的 Active Constraints 还属于可承受范畴(官网本人都感觉没问题),不须要去专门破费大量工夫去排查优化。

感激题主午休达人 @UWA 问答社区提供了答复

封面图来源于网络


明天的分享就到这里。生有涯而知无涯,在漫漫的开发周期中,咱们遇到的问题只是冰山一角,UWA 社区愿伴你同行,一起摸索分享。欢送更多的开发者退出 UWA 社区。

UWA 官网:www.uwa4d.com
UWA 社区:community.uwa4d.com
UWA 学堂:edu.uwa4d.com
官网技术 QQ 群:465082844

退出移动版