UIRoot 屏幕适配

  • 文章说明
  • 屏幕适配
    • UIRoot
      • 1.原理简述
      • 2.举例说明
    • Constrained
      • 1.原理简述
      • 2.举例说明
  • 源码
  • 思考

文章说明

本篇文章基于NGUI (3.12.0)版本源码下的代码分析,如果代码和大家自己的不同,可能是版本不同。如果文章中分析有误希望大神看见指点迷津,大家好,我就是一个勤勤恳恳爱偷懒的码农,希望和大家一起学习研究。

屏幕适配

其实之前对屏幕适配只是了解和使用,利用 anchor 设置一些对象的固定位置。直到遇到一个小问题让我思考良多,所以非常想写一篇文章记录一下,原因是因为几个3D模型通过 camera 将其渲染到一张 贴图(Texture)上,非背景的贴图还好,但是如果是作背景的 Texture 不可以设置一个固定的大小比率,因为在不同手机的分辨率下 Texture 会出问题,这个时候就要思考需要给 Texture 根据屏幕适配 size,但是会出一个问题,就是贴图比率设置不好图会变形,但是这不是我们这篇文章的重点,我们的重点是谈一谈关于 NGUI 的屏幕适配。

UIRoot

UIRoot 中有一个 “Scaling Style” 属性,含有三个基本的选项,如下:

  • Flexible
  • Constrained
  • ConstrainedOnMobiles
    有的项目需要,通常会修改NGUI源码,加上一些自定义的选项,但是其实最终效果和这些原理差不多。

1.原理简述

flexible:的原理主要是通过,限制屏幕显示的最小高度和最大高度然后去设置屏幕中真实显示的像素范围,如图:

2.举例说明

举个例子:
图中这个手机的分辨率是:1334*750
表示这个手机,宽度是1334,高度是750,
但是我们设置的这个高度范围是 [760,800],即最小高度是760,最大高度是800,所以这个手机实际像素比我们最小的高度760还要小,那么它就会重新计算这个显示的像素大小:

  • 如果这个手机高度比我们设置的高度还要小,那么这个实际显示的高度就是最小高度,并且重新计算宽度。
  • 如果这个手机高度比我们设置的高度还要大,那么这个实际显示的高度就是最大高度,并且重新计算宽度。
  • 如果这个手机的高度在我们限制的范围内,那么这个实现显示的高度就是这个手机的高度。

比如例子中,这个手机分辨率是:1334 * 750,那么需要重新计算实际显示的宽度和高度。

实际显示的高度是:760,
实际显示的宽度计算如下:
首先计算 手机像素的 宽高比:宽度 / 高度 = ratio
因为:实际显示的宽度 / 实际显示的高度 == radio
所以,实际显示的宽度 = 760 * radio = 760 * (1334 / 750) = 1352(四舍五入取整)
所以手机实际显示的像素大小应该是:1352 * 760

如图使用一张贴图验证一下:

Constrained

1.原理简述

Constrained 的原理就是,设置一个最小的宽度,还有一个最小的高度,然后根据是否勾选 Fit 表明是否需要适配,最后根据这些设置去重新计算实际显示的宽度和高度,如图所示:

2.举例说明

上图中以小米8为例,分辨率是:2248 * 1080
我们设置的屏幕最小宽度是:1280,最小高度是:720
这个时候你肯定会好奇,为啥 Constrained 有一个蓝色的框,但是 Flexible 没有,没错这点非常重要,接下来会讲。
(这里我们只分析 默认 宽高都是 Fit 勾选的情况下,即都默认需要适配)

首先我们需要计算出我们设置好的适配范围的宽高比
1280 / 720 = 16 / 9 = 1.7778
然后我们需要计算出手机分辨率的宽高比
2248 / 1080 = 2.0815

开始分析:

  • 如果 手机像素的宽高比 > 我们基础设定范围的宽高比, 那么说明手机相对我们的基础设置来讲,屏幕更宽,高度更窄,所以我们需要限制它的高度,不能超过我们设置的最低高度 720,同时需要重新计算实际显示的宽度。(会出现蓝色边框,大小范围是 1280 * 720)

  • 如果 手机像素的宽高比 < 我们基础设定范围的宽高比,那么说明手机相对我们的基础设置来讲,屏幕更高,宽度更窄,所以我们需要限制它的宽度,不能超过我们设置的最低宽度 1280,同时需要重新计算实际显示的高度。(会出现蓝色边框,大小范围是 1280 * 720)

  • 如果 手机像素的宽高比 == 我们基础设定范围的宽高比,正常显示,不用调整。(不会出现蓝色框)

所以小米8,实际显示的高度是:720
因为,实际显示的宽度 / 实际显示的高度 == 小米8像素宽度 / 高度
所以,实际显示的宽度 = 720 * (2248 / 1080 = 2.0815 )= 1499(四舍五入)
所以屏幕中实际显示的大小是:1499 * 720

使用一张贴图验证一下:

源码

其实吧 UIRoot 代码很少,而且也非常简单,这里我就只粘贴最核心的重新计算实际屏幕宽高相关的代码:

 [DoNotObfuscateNGUI] public enum Scaling{Flexible,Constrained,ConstrainedOnMobiles,}[DoNotObfuscateNGUI] public enum Constraint{Fit,   //宽度和高度都要适配Fill,   //设计和 fit 相反FitWidth,  //只有宽度适配FitHeight,  //只有高度适配}public Constraint constraint{get{if (fitWidth){if (fitHeight) return Constraint.Fit;return Constraint.FitWidth;}else if (fitHeight) return Constraint.FitHeight;return Constraint.Fill;}}//核心代码public int activeHeight{get{Scaling scaling = activeScaling;if (scaling == Scaling.Flexible){Vector2 screen = NGUITools.screenSize;float aspect = screen.x / screen.y;//屏幕高度不在 [minimumHeight, maximumHeight] 的范围的屏幕需要重新计算它的屏幕高度和宽度if (screen.y < minimumHeight){screen.y = minimumHeight;screen.x = screen.y * aspect;}else if (screen.y > maximumHeight){screen.y = maximumHeight;screen.x = screen.y * aspect;}// Portrait mode uses the maximum of width or height to shrink the UIint height = Mathf.RoundToInt((shrinkPortraitUI && screen.y > screen.x) ? screen.y / aspect : screen.y);// Adjust the final value by the DPI settingreturn adjustByDPI ? NGUIMath.AdjustByDPI(height) : height;}else{Constraint cons = constraint;//如果是基于高度适配,直接返回项目基础开发的默认高度if (cons == Constraint.FitHeight)return manualHeight;Vector2 screen = NGUITools.screenSize;//计算屏幕的宽高比float aspect = screen.x / screen.y;//计算基础开发设置的 屏幕宽高比float initialAspect = (float)manualWidth / manualHeight;switch (cons){case Constraint.FitWidth:{// 如果只是适配宽度,也就是说 宽度不随屏幕的宽度变化,那么就需要根据 屏幕宽高比,计算基础的高度// 基础宽度 / 需要显示的高度 = 屏幕宽度 / 屏幕高度 ,所以计算 需要显示的高度值即可return Mathf.RoundToInt(manualWidth / aspect);}case Constraint.Fit:{// 说明是基于宽度和高度适配,设置了需要显示的最小宽度和最小高度// 如果 屏幕实际的宽高比 > 基础的宽高比 --> 说明屏幕比基础设计的要宽,需要对高度进行缩放,不能低于最低高度,即:宽度可以变,高度不变// 如果 屏幕实际的宽高比 < 基础的宽高比 --> 说明屏幕比基础设计的要寨,需要对宽度进行缩放,不能低于最低宽度,即:宽度不变,高度可以变return (initialAspect > aspect) ?Mathf.RoundToInt(manualWidth / aspect) :manualHeight;}case Constraint.Fill:{// fill 的设计思路和 fit 相反// 如果 屏幕实际的宽高比 > 基础的宽高比 --> 宽度不变,高度可以变// 如果 屏幕实际的宽高比 < 基础的宽高比 --> 高度不变,宽度可以变return (initialAspect < aspect) ?Mathf.RoundToInt(manualWidth / aspect) :manualHeight;}}return manualHeight;}}}

思考

由此可见,如果我们开发过程中,给屏幕做了适配,那么可能手机中真实看到的大小并不是手机真正的像素大小,所以对一些屏幕坐标相关的功能,就要特别注意,比如获取屏幕中左下角,右上角的坐标。

Unity 之 NGUI UIRoot 的屏幕适配问题相关推荐

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

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

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

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

  3. Unity 利用NGUI做屏幕分辨率适配+学习UIDraggablePanel的使用

    2019独角兽企业重金招聘Python工程师标准>>> 大家使用unity,一定有看中其跨平台的强大功能,因此也难免会遇到不同屏幕分辨率适配的问题. 先说说UIRoot.在新版本的n ...

  4. Unity NGUI屏幕适配

    前段时间整理的一篇关于unity ui开发的文章,被推荐上了csdn首页,对于刚刚写文字的我来说,是莫大的鼓励,让我干劲十足,写出更多有质量的文字. 写在前面 屏幕适配是每个手机应用和游戏都会解决的问 ...

  5. Unity中的UGUI屏幕适配

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

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

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

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

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

  8. unity屏幕适配以及坐标点适配

    好久没更新了,最近忙着实习和毕设,虽然还没忙完但是也来更新一些在工作中学到的一些知识吧.今天记录一下如何设计屏幕适配和坐标点适配的功能. 首先我们需要确认自己的原图和背景的长宽比例,然后获取屏幕的长宽 ...

  9. 有效解决3D游戏边缘锯齿现象及全面理解LayaAir引擎游戏屏幕适配!

    有的时候看到一些3D游戏锯齿感特别明显,与一些开发者沟通后发现,其实很多人并不清楚怎么能去掉明显的锯齿感,而这并不是只有新开发者才遇到的问题,很多游戏研发经验丰富的开发者,甚至是使用LayaAir引擎 ...

最新文章

  1. Day 13 老师应该要让课堂有趣吗
  2. 【Python-ML】SKlearn库原型聚类KMeans
  3. pytorch 模型可视化_【深度学习】高效使用Pytorch的6个技巧:为你的训练Pipeline提供强大动力...
  4. GY39传感器C语言代码,详解Arduino GY-30数字光强传感器应用
  5. mongodb服务安装及部署配置
  6. gridview隐藏列的方法
  7. 利用匈牙利法求解指派问题
  8. 红米k30 允许调用gpu调试层_高效渲染!RTX 3090卡皇打造NVIDIA STUDIO强力主机实战体验|nvidia|显卡|gpu|cpu|内存...
  9. 如何运用3DGIS技术整合智慧社区综合管理解决方案
  10. tan和cot的梗_sin cos tan cot 之间的关系
  11. 古典音乐入门的常见问题
  12. 网上很牛逼的IT技术网站
  13. 前端背景图放置_html 多张背景图片并存
  14. java 打印机类printer_GitHub - 505058216/thermal_printer: Java实现网络小票打印机自定义无驱打印...
  15. 方兴东:博客网倒掉是十亿美金的教训
  16. 知意字稿的语音转文字功能真的好用吗?
  17. R中 %in% 运算符取反
  18. 谷歌老闪退啊 和 pycharm版本问题 and 微信闪退
  19. 说说自己理解的web架构
  20. 【Openmv】Openmv脱机运行教程

热门文章

  1. 论文解读|算子分裂算法中的安德森加速法
  2. Zygo干涉仪面形滤波详解
  3. springboot 部署微信小程序后台
  4. java实验报告心得体会通用,不可思议!
  5. 家庭小炒菜谱大全 家庭小炒做法大全
  6. MP丨细胞培养系列产品大盘点
  7. 比尔·盖茨微博泄露使用手机为三星Focus
  8. 为什么大公司都不用mfc和qt_手刷POS机为什么有秒到提现费
  9. 幂次法则power law
  10. 这所院校23年录取610人,政英单科线38分,初试过线47分全部录取!