查看原文
其他

社区交流|每周Unity Q&A

Unity Unity官方平台 2018-11-15

Unity技术支持工程师陈嘉栋每周都会总结出,过去一周在Unity官方社区交流群中比较有代表性的问题。本篇文章涵盖了IL2CPP、脚本、VR、图形、编辑器、地形等多个方面,着重介绍在原生的地形系统中使用ASTC格式纹理导致Crash的问题。


社区交流Q&A回顾:

地形

问题01:在Unity 2018.1版本中,地形使用的纹理格式为ASTC,手机上出现了崩溃的问题,如何解决?



回答:这是一个Bug,已在Unity 2018.3 beta以及Unity 2018.2.4 f1版本中进行修复。目前在原生地形中使用ETC2格式的纹理是没有问题的。所以建议在地形中使用ETC2纹理格式。


我们可以通过Crash日志信息,来看看程序是在哪一步Crash掉的。下面分享如何通过Crash日志来还原堆栈信息。


以使用Unity 2018.1.0f1,以及使用的Script Backend是Mono为例。打开手机上的测试程序,查看程序Crash时的日志,如下图所示。



在这份堆栈信息里,我们可以看到例如0049b647这样的数字,它们是在Crash时,程序正在执行的方法的内存地址。每行的结尾则是所使用的库,这里是libunity.so。但内存地址对我们而言没有什么意义,所以下面我们需要将内存地址转换成可以看懂的内容。


在Unity 5.3.6之后的版本都提供了libunity的符号表。


  • 在Mac上,符号表的路径是:

    /Applications/Unity/PlaybackEngines/AndroidPlayer/Variations/mono/Release/Symbols


  • 在Windows上,符号表的路径是:

    C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Symbols\armeabi-v7a\libunity.sym.so


有了符号表,接下来我们还需要NDK的addr2line工具。你可以在NDK目录下找到:

toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line


万事俱备,接下来我们解析第一条内存地址所对应的方法。

./arm-linux-androideabi-addr2line -f -C -e   libunity.sym.so 0049b647


可以看到Crash的方法是:



construct_block_size_descriptor_2d似乎还不太明显。我们再往回追。



原来是在做DecompressASTC相关的操作时Crash了。


请注意:使用的符号表版本一定要和打包所使用的Unity编辑器版本一致。


Plugins

问题02:Unity是否在Android平台支持64位动态库的调用?

 

回答:在Unity2018.1.0 Beta 2版本中提供了对 Android 64-bit ARM(experimental)的支持。而在Unity 2018.2正式版中,对ARM64的支持应该已经很完善了。


请将Scripting backend设置为IL2CPP后,就可以在Player Setting中选择ARM 64了。

 

编辑器

问题03:如何获取Animationclip的检视窗口显示的该资源的内存占用大小数据?


回答:可以调用AnimationUtility.GetAnimationClipStats(clip)来获取某个Clip的状态,即AnimationClipStats类的实例,其中的Size字段即检视窗口显示的内存占用大小。


请参考下面的代码:

Assembly asm = Assembly.GetAssembly(typeof(Editor));

getAnimationClipStats = typeof(AnimationUtility).GetMethod("GetAnimationClipStats", BindingFlags.Static | BindingFlags.NonPublic);

Type aniclipstats = asm.GetType("UnityEditor.AnimationClipStats");

sizeInfo = aniclipstats.GetField("size", BindingFlags.Public | BindingFlags.Instance);


另外,C#部分有开源的代码。请参考Github上的代码:

https://github.com/Unity-Technologies/UnityCsReference/blob/3cfc6c4729d5cacedf67a38df5de1bfffb5994a3/Editor/Mono/Inspector/AnimationClipEditor.cs


图形

问题04:Tonemapping和打包设置里Colorspace是冲突的吗?使用Ronemapping,Colorspace是否需要设置为线性?


回答: 使用Tonemapping要用到HDR,最好和线性空间一起用,才能保证准确度。如果项目设置为Gamma的话,Postprocessing中的Color Grading会有一个警告的。



问题05: 摄像机可以开HDR,但是打包到手机渲染设置中默认是不开的,是否可以使用HDR计算出来的结果,通过Mapping转换成LDR给手机显示?


回答: Tonemapping的作用也是为了将一个高动态范围的颜色数据映射回可用颜色空间,为的是不被显示屏幕截断色彩。因为显示器很少支持HDR,Android手机更是565颜色居多。Tonemap就是一个简单S曲线Remapping。



问题06:摄像机开启HDR并不表示移动端开启HDR吗?

回答:手机上不是固定fp16的,可以自行调整,如果设置没有Hdr backbuffer, 则摄像机上的标记也没有用。


下面是一些相关的小贴士,帮助大家科普Graphic Setting中的各个tier和设备的对应关系。Graphics Settings内的Tier设置,在运行时会根据GPU来选择对应的Tier。应用相关的设置。具体各个Tier和设备的对应关系如下:


Tier 1:

Android - all devices that have support for OpenGL ES 2 only

iOS - all devices before iPhone 5S (not including 5S, but including 5C), iPods up to and including 5th generation, iPads up to 4th generation, iPad mini first generation

Desktops: DirectX 9, HoloLens


Tier 2:

Android - all devices with OpenGL ES 3 support,Vulkan

iOS - all devices starting from iPhone 5S, iPad Air, iPad mini 2nd generation, iPod 6th generation

AppleTV


Tier 3:

Desktops: OpenGL, Metal, DirectX 11+,Vulkan


具体内容请查阅相关文档。



问题07:如何实现雪地踩踏的效果,需要曲面细分的效果,类似《古墓丽影》这样的效果?


回答:思路并不复杂,就是Mesh变形。



《古墓丽影》的实现,请参考:

http://tombraider.tumblr.com/post/131825841425/dev-blog-snow-tech-and-houdini-simulations-mike


你也可以参考文章《利用Shader给斯坦福兔子长毛和实现雪地效果》:

https://www.cnblogs.com/murongxiaopifu/p/7887614.html 



问题08:如何实现一团纹理在球上面随机方向位移,并且随时间变化?


回答:采样的时候以_Time作为种子取个噪声即可,请参考《Shader特效—实现“噪声”》:

https://blog.csdn.net/panda1234lee/article/details/52085375



问题09: 如何实现扰动的方向是随机的?在脚本里Setfloat感觉是硬切的。



回答:可以从一张噪声贴图里读取。



请参考与失真效果的文章《着色器-冰效果》:

https://zhuanlan.zhihu.com/p/37696836



问题10:Unity自带的屏幕射线反射效果一般,有更好的推荐吗?


回答:可以参考文章《Unity_StochasticScreenSpaceReflection-实现篇》:

https://zhuanlan.zhihu.com/p/38303394


IL2CPP

问题11:GZipStream在Unity编辑器中工作正常,但Android手机上没办法正常工作。查看Logcat发现在执行时抛出了下面的异常,如何解决?



回答: 如果项目的Scripting backend使用的是Mono,则在使用System.IO.Compression命名空间时的确会抛出类似上面的异常。但是如果使用IL2CPP的话,System.IO.Compression命名空间是可以正常使用的,包括GZipStream同样也是可以正常使用的。


脚本

问题12:如何求一个数最大能是2的多少次幂啊? 例如:513最大是2的9次幂,就多了一位数。Math里有没有这样的方法,我想要模拟Cullingmask那样的筛选层。


回答:范围小用查表,尽量限制在512之内。范围大用位移 ,但不要用浮点运算。



请参考下面的代码:

int Exp(int i)
{
    int counter = 0;
    while(i > 1)
    {
        i = i >> 1;
        counter++;
    }
    return counter;
}
 
void outpuLayers(int layerValue)
{
     
    while(layerValue > 0)
    {
        int i = layerValue;
        int counter = 0;
        while (i > 0)
        {
            i = i >> 1;
            counter++;
        }
        Debug.Log(counter);
        i = 1;
        while (counter > 1)
        {
            counter--;
            i = i << 1;
        }
        layerValue = layerValue ^ I;
    }
}

VR

问题13:在Unity 2017.1中进行开发Windows Mixed Reality时,Unity编辑器会报错“RenderTexture.GenerateMips failed: render texture does not have mip maps (set useMipMap to true).”这是一个Bug吗?


回答:这是一个Bug,已经在Unity 2017.4版本中进行修复。


需要特别说明的是Unity 2017.4是LTS版本,会持续修复已知的所有Bug,所以建议使用Unity 2017.4进行开发。Unity版本说明请参考:Unity全新的版本发布计划


小结

以上就是过去一周Unity官方社区交流群中比较有代表性的问题,其中有你关注的问题吗?如果你也希望与Unity的技术工程师交流,欢迎加入Unity官方社区交流群:629212643 或访问Unity官方中文论坛(Unitychina.cn)!



推荐阅读


优惠促销

8月Asset Store资源商店促销 

8月期间,只需在Asset Store资源商店消费满50-255美元,即可获赠2-6款精品资源,最高消费250美元,更可附赠获得一件Asset Store定制款T恤!

活动地址:

https://assetstore.unity.com/g/august-promo-activation-demo



点击“阅读原文”访问Unity官方中文论坛

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存