前段时间整理的一篇关于unity ui开发的文章,被推荐上了csdn首页,对于刚刚写文字的我来说,是莫大的鼓励,让我干劲十足,写出更多有质量的文字。

写在前面

屏幕适配是每个手机应用和游戏都会解决的问题,当然在开发的过程中会遇到各种各样的坑,这次,我们就来讨论一下unity项目中的屏幕适配吧!

目录

  1. 屏幕适配的分类
  2. 哪些内容需要适配
  3. unity中常见的适配方式
  4. 游戏内容适配
  5. NGUI的适配方案
  6. UGUI的适配方案

屏幕适配的分类

说到屏幕适配的分类啊,也许会有所疑问,屏幕适配还能分类?细致分析一下,可以分为两大类:分辨率适配和宽高比适配。

  1. 分辨率适配
    首先得知道分辨率是什么?分辨率是屏幕显示图像的紧密度,是指显示器能显示的像素有多少。屏幕上的点、线、面都是由像素组成的,分辨率越高,同样大小的屏幕能显示的像素越多,画面就越精细。现在PC上分辨率大多是 1920 * 1080,我们看的视频很多高清版本就是 1080p 的。
    既然分辨率是屏幕的一项指标,那么手机上当然也会用到,现在智能手机市场有那么多产品,有多个厂家生产,并且有多个价位,所以手机屏幕分辨率肯定各不相同(虽然屏幕分辨率一般比较固定的几个)。那么分辨率适配是每个应用、游戏都应该做的。

  2. 宽高比适配
    这个很好理解,每个手机大小各不相同,宽高比也会有多种啦,适配宽高比当然也是必须要做的喽。

    当下移动设备主流分辨率及宽高比:
    iOS设备的分辨率主要有:

    Android设备的分辨率则相对纷杂,主流的分辨率有:

哪些内容需要适配

  1. User Interface
    游戏UI需要适配,这是无所质疑的,包括一般的手机应用程序,都需要这个步骤。如果再细分一下,还分为位置适配和大小适配

    位置适配:分辨率会影响UI在屏幕中显示的位置,比如在800 * 600分辨率的屏幕上,button1在正中央位置,坐标为(400, 300),但是如果放在1366 * 768分辨率屏幕上位置就会靠左边一些,这样会严重影响UI布局的美观。

    大小适配:同样的例子,在800 * 600分辨率的屏幕上,button1的大小为50*20像素,但是到了分辨率高的屏幕上,button1就变得很小了,影响美观,影响用户正常使用。

  2. 游戏内容
    一般的应用开发,用户看到的只有UI,但在游戏中,除了UI,还有游戏内容。而游戏内容是什么呢?

    举个例子:
    比如在2D游戏中,除了那些可以交互的按钮滚动,在二维场景中的背景、物件、NPC等,都属于游戏内容。在进行宽高比适配的时候,难免会按照宽度或高度做一些裁剪,如果不进行处理,有些游戏内容就会看不到。
    在3D游戏中,场景的大小是固定的,当相机照射的宽高比因为适配屏幕宽高比变化时,就可能“穿帮”,很有可能看到黑边。

    在unity中不管2D游戏还是3D游戏,分辨率大小不会影响游戏内容显示,屏幕宽高比会影响游戏内容显示。

    注意:在unity编辑器中,game视图是默认的视口,并且编辑器下改变游戏宽高比,unity会自动把相机宽高比调整到适配的宽高比。

unity中常见的适配方式

  1. Camera组件
    Projection:投影类型
    Prespective为透视投影

    Field of View:相机的张角,它决定相机照射的范围。
    Clipping Planes:近裁剪面和远裁剪面
    Viewport Rect:视口大小,取值为0 ~ 1之间

    Orthographic为平行投影

    与透视投影不同的是size属性,它用来调整摄像机的大小
    orthographicSize:等于相机高度的一半

    注意一下,unity中的单位和像素之间有一个转换关系,叫做Pixels To Units

    默认为100,unity中一个单位表示图片的100个像素。如果游戏屏幕高为800像素,那么换算后高度为 800 / 100 / 2 = 4。

    unity没有直接设置摄像机宽度的属性,也没有获取摄像机宽度的接口,但可以通过高度和宽高比计算出来。那么计算宽度如下:

    cameraWidth = camera.orthographicSize * 2 * camera.aspect

    换算成像素:cameraWidth * 100

    cameraHeight = camera.orthographicSize * 2

    换算成像素:cameraHeight * 100

    相机的宽高比是unity自动设置为当前屏幕宽高比的,所以camera.aspect不需要自己设置。

  2. 缩放
    在Transform组件上,可以设置控制物体每个方向上的缩放比例。

  3. 锚点(相对位置)
    目前NGUI,UGUI都有类似的功能,稍后再讨论。

游戏内容适配

游戏内容可以分为两类
有效内容:游戏中一定需要显示在屏幕上的内容
实际内容:包括有效内容和为了适配、或其它目的增加的内容。

  1. 3D游戏中把要么场景做得比正常显示时更大一些;要么显示天空盒子。

  2. 2D游戏中也是把背景做得大一些,尽可能让游戏不出现黑边。
    我们的开发一般都会选择在一个固定的设计分辨率上进行,比如常用的iOS竖屏游戏设计分辨率640*960,我们就以这个设计分辨率为例。通常情况下,设计分辨率尺寸就是我们游戏有效内容的尺寸。
    orthographicSize设置为4.8,就可以让游戏内容铺满屏幕

    这里有一篇文章,里面详细讲了unity 2D游戏的屏幕适配。

NGUI适配方案

  1. UIRoot
    NGUI中每一个UI都是以UIRoot作为根节点,该组件完成了NGUI大体上的适配功能。
    UIRoot的几种缩放方式:

    Flexible:

    在该模式下,下面的UI都是以像素为基础,100像素的物体无论在多少分辨率上都是100像素,这就意味着,100像素在分辨率低的屏幕上可能显示正常,但是在高分辨率上就会显得很小。

    在该模式下,UIRoot的属性如下:

    Minimum Height:设置为725时,当屏幕高度小于725时,在该屏幕上显示的样子和开发时一致。
    Maximum Height:设置为1024时,当屏幕高度大于1024时,在该屏幕上显示的样子和开发时一致。

    Shrink Portrait UI:当是竖屏状态时,按宽度来适配。
    Adjust by DPI:使用dpi做适配计算。

    补充一下一些关于屏幕的基本概念

    dip:设备无关像素
    dp:就是dip
    px:像素
    dpi:像素密度,单位面积上有多少个像素点
    分辨率:宽高两个方向上的像素点数,如800*600
    屏幕尺寸:屏幕对角线长度
    屏幕比例:宽高比

    详细的转换关系,去这里看看。

    开发时的布局:

    改变Game视图大小:

    改变Game视图大小,高度大于725,小于1024,(按刚刚的截图中设置的值测试的):

    在高度在Minimum和Maximum之间时,UIRoot就不会对下面的UI缩放了,开发时有多少像素在高分辨下也只有那么点像素,所以看起来就变小了。

    这个Minimum和Maximum Height用于你对实际的屏幕尺寸进行限制,如果实际的屏幕尺寸小于Minimum,那么就相当于设置了“Constrained”模式、Manual Height值设为Minimum的时候一样,同理,如果屏幕尺寸超过了Maximum,那也相当于设置了“Constrained”模式、Manual Height值设为Maximum的时候一样。

    以上是在Flexible模式的关于分辨率的适配,还有一个是宽高比适配,分两种情况:

    当高大于宽的是,也就是竖屏状态时

    两边被截了

    只需要勾上Shrink Portrait UI,就能按照宽度来适配了(因为默认横屏状态,并且默认按高度适配,所以在看这段源码的时候,它里面的计算是宽高颠倒的):

    当宽大于高时,也就是横屏状态时:就需要自己来根据宽度来调整缩放。

    • 动态的改变适配的高度

      public class NewBehaviourScript : MonoBehaviour {public int ManualWidth = 1280;public int ManualHeight = 720;void Awake () {UIRoot uiRoot = gameObject.GetComponent<UIRoot>();if (uiRoot != null){if (System.Convert.ToSingle(Screen.height) / Screen.width > System.Convert.ToSingle(ManualHeight) / ManualWidth)uiRoot.minimumHeight = Mathf.RoundToInt(System.Convert.ToSingle(ManualWidth) / Screen.width * Screen.height);elseuiRoot.minimumHeight = ManualHeight;}
      }
      }
    • 利用相机的camera.orthographicSize
      需要知道orthographicSize表示的是相机高度的一半,前面已经讲清楚了。我在16 : 9屏幕下开发,并且设置camera.orthographicSize为1,把Minimum和Maximum设置为相同

    ,然后把下面脚本挂在UI相机上:

    public class NewBehaviourScript : MonoBehaviour {void Awake (){camera.orthographicSize *= 16.0f / 9 / ((float)Screen.width / Screen.height);
    }
    }

    16:9屏幕上正常:

    不加上述脚本,在5:4屏幕上,两边被裁剪了:

    加上上述脚本,在5:4屏幕上就正常了,按照宽度适配:

    Constrained:

    该模式下,屏幕按照尺寸比例来适配,不管实际屏幕有多大,NGUI都会通过合适的缩放来适配屏幕。这样在高分辨率上显示的UI就会被放大,有可能会模糊。

    Content Width:按照该宽度值适配屏幕
    Content Height:按照该高度值适配屏幕

    Fit选项表示已哪个值做适配。这两个值可以认为是事先设定好的屏幕初始大小和比例。源码中Fit选项的枚举值:

    public enum Constraint
    {
    Fit,
    Fill,
    FitWidth,
    FitHeight,
    }
    • 如果Fit都没勾选(Constraint.Fill)
      当适配宽高比小于实际宽高比时,就会按照宽度适配,反之按照高度适配。该情况下可以保证显示结果永远没有黑边,但上下或者左右两边可能会被裁剪。

    • 如果勾选了Width(Constraint.FitWidth)
      那么就会在屏幕比例发生变化时,按照宽度来适配。例如开发时用16:9屏幕,运行在5:4屏幕上,宽度适配,计算公式为 activeHeight = manualWidth / (screen.x / screen.y),16 / ( 5 / 4 ) = 12.8 > 9,这样显示宽度就全部显示进来了,但是高度上就会出现黑边,所以这种情况下要想办法解决黑边问题。

    • 如果勾选了Height(Constraint.FitHeight)
      那么就会在屏幕比例发生变化时,按照宽度来适配。activeWidth = manualHeight * (screen.x / screen.y),9 * ( 5 / 4 ) = 11.25 < 16,这样高度全部显示进来,但在宽度上两边被裁剪掉了,显然这样更不合适了。

    • 如果两个都勾选了(Constraint.Fit)
      当适配宽高比大于实际宽高比时,就会按照宽度适配,反之按照高度适配。该情况下可以保证显示开发时能见到的所有内容,但是可能上下或左右会出现黑边。

    下面是UIRoot.cs源码:

    可以清楚的看到NGUI是怎么利用这些值进行计算高度的。

    Constrained On Mobiles

    前两种模式的组合,在PC和Mac等桌面设备上用Flexible模式, 在移动设备上Constrained模式。

  2. UIAnchor or UIStretch
    作为NGUI中一个组件,但之前做的项目里面好像怎么用,可以把它看做对一个UI树中的局部进行控制。它们在处理细节上很相似,都是先计算参照对象(这个参照对象由Insprector的Container指定,如果没有选择,就是Camera)的大小Rect,然后根据参数UIAnchor(Side,relativeOffset,pixelOffset),UIStretch(Style,relativeSize,initialSize,borderPadding)进行调整,最后设置对应的属性,只不过UIAnchor设置的是transform.position,UIStretch设置的是(width,height)或clipRange等。

    UIAnchor组件的视图:

    Container:指定Anchor的参照点,如果没有选择,则以Camera的pixelRect的区域为参照面 。
    Side:锚点位置,有八个位置可选。
    Relative Offset:相对于Camera,或Container的百分比偏移 。
    Pixel Offset:像素的偏移。

    UIStretch组件的视图:

    大致和UIAnchor差不多,Style属性有些改动如下

    Horizontal:横向拉伸。
    Vertical:纵向拉伸。
    Both:双向拉伸,但xy方向上的拉伸比例不同。
    BasedOnHeight:双向拉伸,但xy方向上的拉伸比例相同,且比例基于height。
    FillKeepingRatio:双向拉伸,但xy方向上的拉伸比例相同,比例基于较大者。
    FitInternalKeepingRatio:双向拉伸,但xy方向上的比例相同,比例基于较小者。

    具体的可以自己研究一下,但是不建议用这个两货,折腾了一下感觉太麻烦,而且根本没必要啊,因为UIRoot已经做了大部分的适配了,那些局部细节上的调整完全可以用UIRect所管理的Anchor来实现,它不是单独的组件,比这两简单多了,下面就来聊聊它。

  3. UIRect的Anchor
    首先得了解一些UIRect,这里不详细聊它,后面会整理一篇分析NGUI底层的文章,里面有详细说它。简单介绍一下,从NGUI控件的继承结构上,UIRect是所有weight和panel的基类,管理着rect和anchor,计算、生成,是一个抽象类。

    拿UISprite举例:

    Type:三种类型,使用锚点、基本控制、完全控制。
    Execute:设置在什么时候执行锚点适配。
    Target:参考物体。
    Left、Right、Bottom、Top:该控件上下左右边。

    比如,你想某个按钮在任何尺寸屏幕上都停留在屏幕上的左边,可以如下:

    16:9屏幕上

    锚点设置如下:UISprite的左右边界都参考target的左边

    然后5:4屏幕上,UISprite依然在屏幕的左边了

    当然其它的weight都可以设置锚点,可以这么说,凡事继承自UIRect的组件都可以使用该锚点。

UGUI适配方案

终于把NGUI适配说完了,对于UGUI目前没有深入了解,在场景视图中可以拖拽锚点,设置锚点区域,感觉挺简单的,粗略做个笔记。

  1. Canvas Scaler:画布比例缩放,从整体上对UI进行适配控制,和UIRoot有异曲同工之妙,很多参数名字不一样,但意思一样。

    ConstantPixelSize:按像素适配

    Constant Pixel Size:保持UI元素大小不变,无论屏幕尺寸如何变化,所占像素不变。
    Scale Factor:保持大小的比例 。原图100x100 原始大小1=100x100 原来的2倍大 2=200x200
    Reference Pixels Per Unity: 100 Unity里的1单位大小代表100像素

    ScaleWithScreenSize:按比例适配

    Scale With Screen Size:UI元素大小跟随屏幕分辨率的大小变化而变化。
    Reference Resolution:参考分辨率。
    Screen Match Mode:
    Match Width Or Height:根据参考分辨率的高或宽,来缩放UI元素。
    Expland:分辨率设置不会小于Canvas设置的分辨率。
    Shrink:分辨率不会大于Canvas设置的分辨率。

    Constant Physical Size:按屏幕物理大小适配

    根据屏幕的PPI信息和ConstantPhysicalSize本身的配置信息,得出一个“合适”的scaleFactor,以达到UI在不同PPI设备上的最终大小都是一致的。

  2. 锚点
    UGUI中锚点有多种“形态”,当锚点是一个点时,表示该UI大小不变,位置会随参考点改变。当锚点是一个矩形区域时,UI的大小就会随该参考区域改变,当然非常灵活,锚点矩形的大小可以随意设置,甚至可以在某个方向长度为0。

写在最后

以上就是屏幕适配的所有内容,主要介绍了屏幕适配的分类:分辨率适配和宽高比适配,按内容又分为游戏UI适配和游戏内容适配,并给出一些适配方法。然后重点讲了NGUI的适配方法,简单介绍了UGUI,总的来说UGUI和NGUI适配的方案有很多相似的地方,适配的大致方向就是按像素、按比例缩放对全局适配,用锚点来做精细的控制。对UGUI现在不是很熟,所以写的很简单,以后找时间在详细研究一下,再整理出来。

Unity NGUI屏幕适配相关推荐

  1. Unity+NGUI多分辨率适配方案

    说起unity的适配方案,网上可谓是一查一大堆,但是真正要应用到项目中的时候,总会出现各式各样的问题.由于最近自己要做一个小游戏,在开始做游戏之前,就想着先好好搞一搞适配这块,以后新起项目的时候也会用 ...

  2. Unity 3D 屏幕适配全方面解析!

    转载自 https://www.jianshu.com/p/95cb4621206e 1.游戏屏幕适配 屏幕适配是为了让我们的项目能够跑在各种电子设备上(手机,平板,电脑) 那么了解是适配之前首先要了 ...

  3. Unity关于屏幕适配留黑边的做法

    终于下了决心开始写博客,想来想去还是先写个最近刚解决的问题.RT 我们项目使用的1280*720,也就是16:9的开发屏幕宽高比.因为开始做屏幕适配的时候有点晚了,然后游戏也不是那种很需要操作的,接着 ...

  4. Unity刘海屏幕适配

    华为适配官网网址:http://developer.huawei.com/consumer/cn/devservice/doc/50114 小米适配官网网址:https://dev.mi.com/co ...

  5. UNITY NGUI IPHONEX完美适配

    苹果的IphoneX新增一个安全区的概念,如下图 图中绿色区域为安全区,所有可交互的组件全部放在安全区内,只有背景可以延伸出去,达到全面屏的效果 我们适配IphoneX采用NGUI通用的锚点去适配.默 ...

  6. Unity 之 NGUI UIRoot 的屏幕适配问题

    UIRoot 屏幕适配 文章说明 屏幕适配 UIRoot 1.原理简述 2.举例说明 Constrained 1.原理简述 2.举例说明 源码 思考 文章说明 本篇文章基于NGUI (3.12.0)版 ...

  7. Unity中关于IphoneX的屏幕适配

    关于屏幕适配也在网上找了很多的解决方案,我也总结一下,保证自己能在以后翻出来可以不看代码就能想起完整流程. 屏幕适配,就是为了不同的机型不同的屏幕尺寸做对应的处理,接下来开始正式的流程介绍: 1.先定 ...

  8. Unity中2D游戏多分辨率屏幕适配方案

    一:什么是像素? 像素是由很多个小方格组成,每一个小方格上都存储了位置信息和色彩信息.像素是图像的最小单位 图像分为两类:位图和矢量图 --位图(点阵图):由多个像素组成,当放大时被分为多个色块,而且 ...

  9. Unity中的UGUI屏幕适配

    本文分享Unity中的UGUI屏幕适配 屏幕适配一直是一个老生常谈的问题, 虽然只是项目一开始的时候会用到, 但是还是有很多东西需要学习和了解, 今天给大家分享下一些个人的学习和总结. 各种坐标 屏幕 ...

最新文章

  1. python【蓝桥杯vip练习题库】ADV-272 change(思维)
  2. 【数据挖掘】卷积神经网络 ( 池化 | 丢弃 | 批量规范化 | 卷积神经网络完整流程示例 | 卷积 | 池化 | 全连接 | 输出 | 卷积神经网络总结 )
  3. 489个学位点被撤销,2018撤销和增列学位授权点名单公布
  4. php把数据创建一个表格,PHP创建(导出Excel数据表格)
  5. 升级win11系统需要预留多少磁盘空间 Windows11系统盘需要多少空间的介绍
  6. oracle xsql 详解(一)
  7. 计算机仿真课程建议,关于信息技术教学中的几点建议
  8. 50漂亮的后台管理界面模板
  9. 苹果电脑(macOS)查看 WiFi 密码的两种方法
  10. JWS实现WebService
  11. 女性比男性更聪明、更会投资、事业心更重、对自己更严格?揭秘女性价值崛起的数据真相!...
  12. php秒表计时器,JS实现可暂停秒表计时器的效果(图文详解)
  13. 利用Redis原子计数器incr实现计数器及接口限流
  14. 图像的 matlab代码,常用的一些图像处理Matlab源代码
  15. 搭建公司内部论坛 只需简单三步 1 (安装Discuz)
  16. 宝塔wordpress安装及使用(宝塔wordpress建站教程)
  17. Java —— 内存泄露排查
  18. 通俗易通解释SLAM问题的数学描述:运动方程和观测方程
  19. cpu软改vista 驱动_在Windows 7、8或Vista中启动分配给特定CPU的应用程序
  20. 不求甚解之自制编程语言

热门文章

  1. 基于matlab的LFM脉冲压缩仿真
  2. Go游戏服务器开发的一些思考(一):语言层面
  3. 宝塔7.9最新企业版免授权无后门
  4. 学习思维导图15条常识
  5. python自动写作ai_论文自动写作之自动添加参考文献
  6. 操作系统-请编程建立 3 个并发协作进程,它们分别完成 f(x,y)、f(x)、f(y)
  7. 分布式技术引爆人工智能
  8. 2007成都软件产业十大事件揭晓[转]
  9. 利用Open 3D建立三维模型
  10. ATT并非手机品牌 常见国外定制机运营商