Unity屏幕适配终极方案

发表于2015-04-29
评论1 2.23w浏览

一、分辨率统计

根据最新数据,目前android和ios的分辨率分布如下图1和图2所示:

      http://km.oa.com/files/post_photo/690/228690/d9a9657fe68316af2d282cfc22f52a981421287563.gif

图1 android分辨率分布

 

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image002.gif

 图2 ios分辨率分布

根据上图,我们可以得到一个重要结论,即主流的移动设备的屏幕宽高比(高宽比)的范围在1.33 ~ 1.77之间,这为我们美术上的规划和技术上的适配提供了重要依据。

 

二、2D游戏的适配

对于例如用cocos2d制作的2d游戏,方案比较成熟,主要有以下三种:

1)全屏,不等比拉升画面,该方法简单粗暴,但是导致失真,效果很差;

2)非全屏,等比拉升画面,空余处用背景色填充,效果优于第一种,但是屏幕利用率较低;

3)全屏,等比拉升画面,结合锚点,实现关键UI的完整呈现。

毫无疑问,第三种的效果是最好的,但是实现也是要更加复杂。

 

三、Unity游戏的适配

对于用Unity制作的3d游戏,其适配复杂度比2d游戏会更高一些,需要适配的情景主要包括以下几个方面:

1)UI场景的适配

2)3D场景的适配

3)3D场景下的UI适配

4)UI场景下的3D模型适配

本文主要讨论UI场景的适配。

 

四、UI场景适配

1、关键词解释

我们采用前文所述的第三种方案,即全屏不失真显示,接来下会涉及到五个关键词语:UI元素抽象、屏幕宽高比(高宽比)、基准分辨率、等比拉升、锚点,先分别解释一下。

1)UI元素抽象:如果将UI中所有元素从重要程度抽象成两部分,一部分为有损单元,一部分为无损单元。区分有损和无损对象是适配的关键,因为全屏不失真模式下,不可能做到任何元素都无损。

2)屏幕宽高比(高宽比):在统一的高度(宽度)下,决定了有损单元的损失程度。

3)基准分辨率: 基准分辨率确定了无损单元的基准数据(包括位置、大小等),其他分辨率下则需要基本保持一致。下图解释了UI元素抽象、基准分辨率和宽高比。

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image003.gif

4)等比拉升:即拉升时不修改UI元素的宽高比例,是实现适配的第一把武器。

5)锚点:使无损单元完整显示的一种手段,是实现适配的第二把武器。一般的实现手法是设定一个与摄像机或参照物的距离相对(绝对)数值,当摄像机或参照物发生变化时,该单元也随之变化,基于此可以使它始终保持在屏幕中相对固定的位置。

2、Unity适配原理

对于使用ngui(版本:3.5.6,其他版本在实现手法上稍有出入,但是基本原理一致)的项目,ngui已提供了适配的两把武器:UIRoot(实现等比拉升),UIAnchor &&UIWidget(实现锚点)。

 

UIRoot:一个场景内唯一的ngui根节点,作用是通过设定一个基准高manualHeight,实现整个UI场景的等比缩放。核心函数如下(重点部分红框标示):

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image004.gif

其中activeHeight的计算方式如下:

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image005.gif

由上面我们可以得到缩放因子为 2 / manualHeight,因此所有UIRoot的子对象也都是缩放的,包括position和scale。

缩放有三条非常重要的原则:

  (1)基准高(manualHeight)需要等于基准分辨率的高。

  (2)相同的屏幕宽高比,高度和宽度上完全匹配。

  (3)不同的屏幕宽高比,高度上完全匹配。

   根据第(1)条,我们又得出基准分辨率下,所有UI对象的position、所有UIWidget对象的Dimension,都和屏幕坐标系是一一对应的。也就是说,一个UI对象的局部坐标和屏幕坐标是1:1的映射关系,对象中的材质面片大小和贴图像素大小也是1:1的映射关系,这是非常重要的一条结论,它保证了实际搭建场景时对UI设计稿的精确还原。根据第(3)条,我们知道不同宽高比下,宽度上无法适配,因此该方向上必然出现有损UI单元,因此在设计基准分辨率时,原则上应保证基准宽度不小于有损的可接受范围。

 

UIAnchor &&UIWidget:根据缩放原则第(3)条,我们知道缩放不能解决宽度上适配的问题,而锚点解决了无损单元的适配问题。Ngui提供两种方式,UIAnchor和UIWidget。

UIAnchor提供了相对于camera或其他参照物的相对偏移和绝对偏移。UIAnchor在Insoector中的呈现如下:

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image006.jpg

其中Container是可选参照物,Side是指具体参照位置,有TopLeft,Left,BottomLeft,Top,Center,Bottom,TopRight,Right,BottomRight九个位置可选。Relative Offset和Pixel Offset分别是对Side的相对和绝对位置偏移量,

    具体算法步骤和关键代码:

(1)求参考物的Rect,参考物的优先选取顺序为:widget、panel、camera。

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image007.jpg

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image008.jpg

(2)根据rect求中心坐标,跟Side关联后坐标重新定位,最后  根据绝对偏移量、相对偏移量和rect的尺寸,计算得到一个初步     局部锚点坐标

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image009.jpg

 

(3)将之前计算得到的局部坐标舍去小数点(防止精度问题),并转换成世界坐标。

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image010.jpg

 

UIWidget是所有UI的基类,内置了一个anchor,提供了相对与任一参考物的相对和绝对偏移。Anchor提供了普通和高级两种方式 在Insoector中的具体呈现如下:

普通方式:

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image011.jpg

高级方式:

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image012.jpg

很明显可以看到,普通模式只能选择一个参考物,可以设置被锚点物体的每条边与参考物的哪个side锚定,以及确定对应的相对和绝对偏移量。而高级模式可以选择四个参考物。

普通模式下的算法步骤和关键代码:

  (1)获取被锚物体的边界坐标,通过相对和绝对偏移量计算得到新坐标

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image013.jpg

  (2)根据被锚物体自身的枢轴(pivot)数据,插值获得新的锚点坐标,同时物体的高宽也受其影响。

http://avocado.oa.com/fconv/files/201501/bd6b81d9e6bcb8caa9e367827aed5d59.files/image014.jpg

 

3、Unity适配总结和技巧

(1)合理选取基准分辨率,使得UI有损单元的损失最小。

(2)可以根据不同的宽高比动态调整UIRoot的基准高,确保UI无损单元的完整显示和减少有损单元损失。

(3)UIAnchor可以使用在非UIWidget的组件上,比较独立且比较方便,但是只能选择固定的Side进行偏移,灵活性不太好。UIWidget上的anchor不能独立使用,但是可以选择任意的Side进行偏移,灵活性较好。

(4)有损UI单元(例如背景图)上,尽量不要放置位置信息,因为位置信息通常属于无损信息,拉伸后不利于展示和其他UI适配。

 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

1个评论

  • rajRKO 2017-06-21 1楼
    Viber is a cross-platform messaging application specially designed for instant messaging. Viber was introduced in the year 2010. viber for pc Client software is available for Viber Apk For Android, Viber for iOS, Viber for Blackberry, Viber for Windows Phone, Viber for Windows PC, Viber for iPad and Viber for Mac PC.