截至2017年9月,iOS与Android移动游戏设备比例约为iOS占28%,Android占72%,分辨率比例如下(推荐参考来源:WeTest平台、腾讯移动分析)
通过以上数据可以计算,Android平台1080P以上为50%左右,iOS平台为35%,1080P及以上的设备占所有移动游戏设备的综合比例为72%*50%+28%*35%=46%。但是考虑到Android平台存在较多大屏幕但GPU性能较差的设备,体验流畅优先时会将这部分机型降分辨率处理。通过结合Android TOP100机型的数据,在TOP100的60台1080P手机中, 高端机为20台,占比34%,中端机为35台,占比58%,低端机为5台,占比8%,中端机中大约有50%的设备为保持流畅需要降分辨率运行。所以实际上Android平台有效的1080P设备占比50%*(58%*50%+34%)=31%,即综合来看有效的1080P设备仅占72%*31%+28%*35%=32%。
理论上,1080P图片内存占用是720P的(1080/720)2=2.25倍。在游戏开发过程中实际上还要更高,因为为优化性能考虑,游戏内大部分UI都会被打成一张张图集(一般为1024x1024),而由于UI图片尺寸大多是不规则的,这会造成越大规格的图片排列后产生的空白缝隙越大(未被利用的图集空间),所以1080P下会比720P有额外更多的内存消耗。
结论:尽管1080P的画面表现力和细腻程度比720P更好,但是由于有效的1080P设备占比并不高,并且1080P对内存占用和包体大小的影响程度也很大,综合考虑,我们将游戏的设计分辨率定为720x1280。
目前移动设别主流分辨率有720P、1080P、2K等,所以需要适配市面上不同分辨率的机型,确保不同分辨率下都有合适的画面表现。Unity中导入图片的Pixels Per Unit为默认值100,开发时我们将游戏场景中的所有正交摄像机的Size(即半高)设置为720/100/2=3.6Unit,所有的画布缩放参照分辨率设置为1280x720,在UI不缩放时(native size),正交摄像机显示的画面可以完全还原UI的设计效果,便于开发阶段的UI制作。
由于我们的设计分辨率为720x1280,所以游戏默认渲染分辨率为720P。同时为了充分利用高端设备的硬件,对于1080P及以上的设备我们也提供高分辨率选项,开启时游戏会使用1080P渲染,这不会对UI产生任何影响(因为我们只使用一套720P的UI资源),但是3D场景和特效的显示效果会更加细腻,当然这也会带来更大的性能开销。
Android 7.0中引入了多窗口显示模式(Multi-Window),在手持移动设备上即分屏模式(Spilt-Screen),我们游戏为了支持分屏模式,需要在安卓的清单文件(AndroidManifest.xml)中针对UnityPlayer所在的Activity添加android:resizeableActivity="true"
,开发时可以使用Android原生方法Activity.isInMultiWindowMode判断当前是否处于分屏模式。在用户开启分屏模式时,我们不能简单使用Screen类来获取屏幕的宽高,而是使用原生方法
Activity.getWindowManager().getDefaultDisplay().getMetrics(metrics)
传入的参数是Android.util 包下的DisplayMetrics 类,该类型返回关于屏幕显示的通用信息,其中widthPixels属性和heightPixels属性即我们需要的设备分辨率。所以在Android平台游戏启动时或者监听到onConfigurationChanged时我们要使用上述方法得到当前准确的分辨率并应用到游戏中进行适配。
目前移动设备的主流宽高比有16:9、18:9、19.5:9等,所以需要适配市面上不同宽高比的机型。区别于分辨率适配,宽高比关注的是设备屏幕的长宽比例,通过合适的适配手段来确保在游戏各种宽高比下准确显示,避免出现错位、重叠、显示不全等现象。
我们针对不同的宽高比设定最小内容填充比例16:9和最大内容填充比例19.5:9,宽高比在该范围内时使用通用的锚点适配方案,UI画布随着屏幕拉伸通过锚点定位来自适应(需要美术进行合理的设计)。对部分低于16:9的超宽设备(如iPad等平板设备)进行锁宽,对部分高于19.5:9的超长设备(少部分手机设备)进行锁高,在设定比例范围外的区域进行纯黑色填充。
例如2400x1080(宽高比20:9)的设备,应当进行锁高适配,即保证UI的高度为1080像素,宽度满足最大内容填充比例1080*(19.5/9)=2340像素。而由于我们的设计分辨率是720P,所以按比例对应到UI画布上尺寸则为1560x720单位,示例图如下。
如果是1536*2048 (宽高比4:3)的设备,应当进行锁宽适配,即保证UI的宽度为2048像素,高度满足最小内容填充比例2048/(16/9)=1152像素。根据设计分辨率720P,按比例对应到UI画布上尺寸则为1280x720单位,示例图如下。
如果是2280x1080(宽高比19:9在设定比例范围内)的设备,则直接对UI画布进行等比例适配为1520x720单位。
游戏内针对会宽高比超过18:9的设备提供是否开启刘海屏的选项,同时我们也有刘海屏机型白名单,通过SystemInfo.DeviceModel获取的设备型号如果在白名单内,则会直接以刘海屏模式显示而无需提供选项。
在刘海屏适配模式下,我们设定最大不超过18:9的内容区域(即Safe Area),使UI仅显示在内容区域,开启刘海屏模式时画布左右各会各留出60像素(720P的分辨率下的预设刘海高度,取1/12屏宽),画布缩窄后就会确保两侧边缘的UI显示在内容区域内而不被刘海遮挡。Safe Area的示意图如下所示。
对于超出内容区域而没超过最大内容比例的部分,即带刘海的部分,则只显示不含重要信息的背景图或无法交互的装饰。因此游戏中所有的背景图以19.5:9最大内容比例的分辨率输出为720x1560,以确保在最宽显示时依然有背景图来填充屏幕内容,最大化利用屏幕空间。
例如2280x1080(宽高比19:9)的设备在开启刘海屏后,画布左右需各留出1080/12=90像素,此时内容区UI宽度为2280-(2*90)=2100像素,根据设计分辨率720P,按比例对应到UI画布上尺寸则为1400x720单位,示例图如下。
针对比例超过18:9而不超过19.5:9的设备,如果用户没有开启刘海屏适配,则会使用全面屏适配。出于历史原因,Android默认支持的最大宽高比仅为1.86,不满足我们设定的最大全面屏设备(19.5/9=2.17),所以我们在清单文件AndroidManifest.xml中声明max_aspect值:
<meta-data android:name="android.max_aspect" android:value="2.17"/>
全面屏适配要根据业务和美术的设计需要,美术设计满屏的界面不缩窄画布全屏显示,其它普通UI依然显示在18:9的内容区域内,但处理和刘海屏有差别。UI画布会根据屏幕高度缩窄至刚好18:9的内容区域,而不是两边缩窄固定60像素,以尽可能的铺满屏幕。同样的2280x1080的设备如果没有刘海使用全面屏适配,内容区UI的宽度为1080*(18/9)=2160像素,UI的高度不变,按比例对应到UI画布上尺寸为1440x720单位,而背景图居中显示不受画布尺寸变化的影响。