技术分享连载(九十七)

技术分享连载(九十七)

本期聚集了这些话题:Unity的裁剪规则、捏脸的实现方式、Graphics.Bilt耗时分析、解锁返回游戏时界面显示变形......
UWA一下,你就知道~


我们将从日常技术交流中精选若干个开发相关的问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。

UWA QQ群:793972859
UWA 问答社区:answer.uwa4d.com


制作

Q1:Unity 5.5.4f1,设备华为Honor v10,安卓8.0,横屏游戏拉起竖屏支付后,切换回来游戏分辨率错误,屏幕上一半是黑屏 ,但是NGUI点击位置又是正常的位置(和渲染出来的位置不同,是正常的点击位置)
请输入图片描述

我们是Unity 4.x版本遇到了这个问题,也是出现在Android 8.0,我们看日志,发现是外部对横竖屏进行了修改。尝试在C#层设置分辨率无解。最后我们修改了Unity的UnityPlayerNativeActivity文件,在Android层对进行了分辨率的重新设置,暂时还未发现引起其他坑。

@Override
    protected void onCreate(Bundle paramBundle) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(paramBundle);
        getWindow().takeSurface(null);
        getWindow().setFormat(PixelFormat.RGBX_8888);
        this.mUnityPlayer = new UnityPlayer(this);
        setContentView(this.mUnityPlayer);
        this.mUnityPlayer.requestFocus();
        saveWidthHeight();
    }
@Override
    protected void onResume() {
        super.onResume();
        setLayoutParams();
        this.mUnityPlayer.resume();
    }
private void setLayoutParams() {
        if (Build.VERSION.SDK_INT >= 26) { //android 8.0
            mUnityPlayer.getView().getLayoutParams().width = width;
            mUnityPlayer.getView().getLayoutParams().height = height;
        }
    }
private void saveWidthHeight() {
        if (Build.VERSION.SDK_INT >= 26) {
        Display display = getWindowManager().getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        display.getRealMetrics(dm);
        width = dm.widthPixels;
        height = dm.heightPixels;
        }
    }

该问题来自UWA问答社区,感谢赵林提供了回答如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a5da1082e34cb42a0a4e832


资源管理

Q2:我想问下Unity的剪裁规则是什么?这个问题在2015年刚出IL2PP的时候非常常见。

官方也一直没有给出明确的规则,比较粗糙的方案是添加link.xml。几个插件解决方案的参考:http://forum.arongranberg.com/search?q=il2cpp

前段时间我做SLua白名单裁剪的时候遇到类似的问题。我理解有以下几个部分:

  • link.xml指定的不会被裁剪(不过文档说支持通配符,我没试出来)
  • 出包时依赖的资源(就是Editor.log里那部分)会被自动分析
  • PreserveAttribute标记

最麻烦的地方在于打包进AssetBundle的资源:打进AssetBundle的资源里有Animator Controller,但是外面的Resources里等都没有;所以默认情况下AC对应的类就被裁剪了,然而运行时候需要所以崩溃。

解决这个可以自己分析YAML,参考:https://docs.unity3d.com/Manual/ClassIDReference.html

PS:其实AC是最玄学的一个东西,这个对应的类我至今还没有摸索透… 我们现在是在Resources下放一个空的AC来规避了。

该问题来自UWA问答社区,感谢钱康来提供了回答,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a66b3bdfa29ca4c81f3d1d6


制作

Q3:我想问下游戏中捏脸的一些具体实现方式。我网上搜索过,资料很少,只搜到过天刀的一篇和介绍Honey Select的一篇,但是看完后仍然有些无从下手的感觉,想知道有没有相关的开源代码可以参考的?

你说的应该是逍遥剑客这篇:https://zhuanlan.zhihu.com/p/28471808
其实HoneySelect压根没加密,直接UnityStudio+dnSpy就可以拆了。

感谢钱康来提供了以上回答

入职之后第一个的系统就是捏脸,当时当然没有康来这么丰富的游戏经验,所以参考的基本是公司内部的资料,大部分功能都是在《Honey Select》中有了,总结一下:

1. 基于骨骼调整。调整骨骼的Scale、Rotation,Position相对用得少,这个在康来提到的博客中写得非常详细了,就不多聊了;

2. 基于Mesh差值。这部分是前面缺失没有提到的部分,在某些骨骼数量有限制或者骨骼不能做得特别好的情况下,会制作两个最大和最小极值的mesh,根据差值计算中间的mesh值,然后在运行时生成最终显示的mesh,和调整骨骼的区别有点类似于骨骼动画和网格动画。

3. 基于材质。在网格不修改的情况下,材质的变化用于肤色、瞳孔颜色、唇色、纹身图案等等,都可以通过材质中的贴图或者参数更改来改变。(UV的变化可以做到纹身颜色的自定义等等)

4. 新的Mesh。这部分在《Honey Select》中也有讲到,也是对于程序来说最为简单,对美术来说工作量最大的部分,用于发型、时装、多余的饰品挂件等等。
至于搜索的关键字,可以考虑:character customization之类的。

额外提下,捏脸的系统要保证运行时效率的同时,预览的速度也要做保证,有时候这两者会有一些冲突,可以通过多方案支持、内存换效率之类的方式来进行优化。如果是手游,最好关注下极限情况下的渲染效率和内存消耗,毕竟如果有材质参数的修改是无法合批的,基于骨骼或者mesh的修改的话对于内存也有一定的额外消耗。

感谢贾伟昊提供了以上回答

该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a6a95d5cd437d6b816b7ef5


渲染

Q4:下图是我们的UWA性能测评报告,其中看到Graphics.Blit的开销还不小,不知道这个是什么用的,能否关掉?
请输入图片描述
请输入图片描述

相机上的HDR是默认勾选的,去掉这个勾选就没有了,在那个位置的Graphics.Blit一般都不是通过脚本添加的相机后处理造成的,而是引擎自身开启的后处理导致,比如HDR或者AA等。

该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a5ebb95f308236c196c1e97


今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站(answer.uwa4d.com)上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(仅限技术交流)