2014-12-31 20:31:02 suntaojiaxin 阅读数 614
  void screenadaptorst()//屏幕适配
    {
        int kuandu = Screen.width;//获取屏幕宽度 
       #if UNITY_ANDROID
        if (Application.platform == RuntimePlatform.Android)
        {
            
        }  
      #elif  UNITY_IPHONE  
        if (Application.platform == RuntimePlatform.IPhonePlayer)
        {
            
        }
      #endif

    }

参考地址:http://blog.csdn.net/dingxiaowei2013/article/details/18454131

2018-06-06 15:54:03 q764424567 阅读数 418

感觉这篇文章不错,转过来跟大家分享

原文作者:雷潮
原文链接:https://www.jianshu.com/p/95cb4621206e
原文來源:简书

1、游戏屏幕适配

屏幕适配是为了让我们的项目能够跑在各种电子设备上(手机,平板,电脑)
那么了解是适配之前首先要了解两个知识点:

1-1、什么是像素?

单位面积中构成图像的点的个数。
特点:单位面积内的像素越多,分辨率越高,图像的效果就越好。

1-2、什么是分辨率?

分辨率可以从显示分辨率与图像分辨率两个方向来分类。
示分辨率(屏幕分辨率)是屏幕图像的精密度,是指显示器所能显示的像素有多少.分辨率的单位有:(dpi点每英寸)、lpi(线每英寸)和ppi(像素每英寸)。
特点:
图像的分辨率越高,所包含的像素就越多,图像就越清晰,印刷的质量也就越好。
同时,它也会增加文件占用的存储空间。

1-3、移动设备分辨率 –以iphone 为例

这里写图片描述

2、什么是适配?

什么是适配?

适应、兼容各种不同的情况

游戏开发中,适配的常见种类

¤系统适配
针对不同版本的操作系统进行适配,例如Unity3D 5.4系统

¤屏幕适配
针对不同大小的屏幕尺寸进行适配,例如Iphone5s,iphone7
iPhone的尺寸
3.5inch、4.0inch、4.7inch、5.5inch
iPad的尺寸
7.9inch、9.7inch
屏幕方向
竖屏
横屏

3、Unity3D 中的屏幕分辨

3-1.

屏幕的宽高比(Aspect Ratio) = 屏幕宽度/屏幕高度

3-2.

Unity2D中摄像机镜头的尺寸决定了我们实际看到游戏内容的多少,在编辑器中我们可以通过调整摄像机Camera的orthographicSize属性值来调整摄像机的大小
这里写图片描述
注:Unity3D中这个比例的默认值是100,即100像素等于1单位。
如果我们的游戏屏幕有640像素高,那么实际换算成单位高度则是6.4个单位,
当我们摄像机的orthographicSize值是3.2时,摄像机大小刚好与屏幕大小相等

4、Unity3D中的屏幕适配设置

4-1:像素适配设置(固定分辨率)

这里写图片描述

4-2、屏幕宽高比

屏幕的宽高比Aspect Ratio = 屏幕宽度/屏幕高度
这里写图片描述

5、Unity3D中的摄像机设置

Unity编辑器中只能直接调整摄像机的高度,那摄像机的宽度是如何确定的呢?
答案就是我们最前面提到的屏幕宽高比。Unity会根据当前屏幕实际的宽高比和摄像机的orthographicSize值来计算出摄像机的宽度值,即:
摄像机实际宽度 = 摄像机orthographicSize * 2 * 屏幕宽高比
即是
摄像机实际宽度 = 摄像机高度 * 屏幕宽高比

我举个例子说明一下,iPhone4的屏幕像素为640*960,宽高比为2:3,假设Pixels To Units值为100,那么如果设摄像机高度size值为4.8,那么摄像机实际宽度按照公式算出6.4,刚好就是屏幕的单位宽度。

6、Unity3D中的图片像素比设置

这里写图片描述

7、Unity3D:关于适配的一些UI问题解决

这里就是重中之重,也是坑点较多的地方

调整相机为设计尺寸,添加Canvas到场景中进行UI设计,但是Canvas默认大小和相机并不重合。

怎么办?

7-1:办法1:

调整Canvas的Render Mode属性为Screen Space - Camera:

将映射游戏内容的Camera拖入Render Camera中,下一个属性Plane Distance表示UI
与Camera的在Z轴距离(其实就是变相反映了UI的Z轴位置)。

接着在Canvas Scaler属性里将Ui Scale Mode属性设置为Scale With Screen Size,
表示Canvas会根据屏幕比例缩放。
下面的Reference Resolution,表示UI宽和高一半的大小。例如设计尺寸为640x960,
则x应为640 / 2 = 320,宽应为960 / 2 = 480。
下面的Screen Match Mode属性选中Match Width Or Height,表示采用宽度(上文有提到过)
或高度(Unity自带适配方式)适配。然后Match调整为0或1,0表示完全宽度适配,
1表示完全高度适配,其他值表示介于两者之间采用比例适配
这里写图片描述

7-2:办法2:

调整Canvas的Render Mode属性为World Space
1、将Event Camera设置为映射游戏内容的Camera。
2、然后调整Rect Transform组件中的Width和Height为设计尺寸的宽和高,同时将Scale属性的X和Y都调整为0.01(对应unity2d默认情况下像素Pixels与引擎单位Unit对应比例100)。这时,Canvas的宽高正好与摄像机相同。
这两种方法都可以将UI调整为与设计尺寸一致,并且在编辑器中运行与真机中运行效果保持一致。
这里写图片描述

7-3:办法3:

给摄像机挂下图脚本就可以搞定比例问题:
这里写图片描述

7-4:设定好就如下图所示

这里写图片描述
解决屏幕分辨率适配的问题,其实就是解决如何让游戏摄像机尺寸限定在给定范围的问题。

8、适配总结

1.游戏有效内容,指游戏中一定需要完整显示在屏幕上的内容;

2.游戏实际内容,指全部的游戏内容,包括有效内容和主要是为了适配多分辨率的或其他不重要的目的而增加的内容。

实际的分辨率适配问题与三个尺寸相关,他们分别是:摄像机尺寸,游戏内容尺寸(包括有效内容尺寸和无效内容尺寸)和实际屏幕尺寸。

9、了解游戏中的摄像机

相机(Camera)
是向玩家捕获和显示世界的设备。通过自定义和操纵摄像机,
你可以使你的游戏表现得真正独特。您在场景中摄像机的数量不受限制。
他们可以以任何顺序设定放置在屏幕上的任何地方,或在屏幕的某些部分。
这里写图片描述

9-1、摄像机属性:

这里写图片描述

Clear Flags 清除标识

确定了屏幕哪些部分将被清除,方便多个摄像机画不同的游戏元素
这里写图片描述
Skybox 天空盒:这是默认设置。屏幕上的任何空的部分将显示当前相机的天空盒。
如果当前的相机没有设置天空盒,它会默认在渲染设置(Render Settings )选择天空盒

Solid Color 纯色
任何空部分,屏幕显示为当前相机的背景色。
Depth Only 仅深度
如果你想绘制一个玩家的枪,又不让它内部环境被裁剪,你会设置深度为0的相机绘制环境,
和另一个深度为1的相机单独绘制武器。武器相机的清除标志(Clear Flags )应设置 为depth only。
Don’t Clear 不清除
此模式不清除颜色或深度缓存。每一帧在下一帧结束后绘制,看上去像是涂抹(smear-looking)的效果。
这在游戏中不常用,最好是在自定义着色器(custom shader)上使用。

Rendering Path-渲染路径

定义什么绘制方法被用于相机的选项
这里写图片描述
Use Player Settings 使用玩家设置:在玩家设置(Player Settings.)相机使用哪个渲染路径。
Vertex Lit 顶点光照 :所有被这个相机渲染的物体都将渲染成Vertex-Lit物体。
Forward 正向渲染:所有对象每材质渲染只渲染一次,和Unity 2.x中的标准一样
Deferred 延迟照明:所有物体将在无光照的环境渲染一次,然后在渲染队列尾部将物体的光照一起渲染出来。

Traget Texture-目标纹理:

这里写图片描述
渲染纹理 (Render Texture)包含相机视图输出。这会使相机渲染在屏幕上的能力被禁止。

补充:Vertex Lit:顶点光照

这个Shader是Vertex-Lit,是最简单的Shader之一。这个Shader渲染代价是非常小的
所有照射在该物体上的光源通过一次光能传递渲染完成并且只计算顶点光源。

因为是Vertex-Lit,所以不会有任何基于像素渲染的效果,例如:Light Cookies,Normal Mapping
和Shadows。这个Shader对模型的细分同样更加敏感,假如在很靠近立方体的地方放置一个
点光源,并且应用这个Shader,这个光源只会在此角落进行计算

General shader performance 通常的着色器性能
Unlit. This is just a texture, not affected by any lighting.�不发光。这只是一个纹理,不被任何光照影响
VertexLit. 顶点光照
Diffuse. 漫反射
Normal mapped. �法线贴图,比漫反射更昂贵:增加了一个或更多纹理(法线贴图)和几个着色器结构
Specular. This adds specular highlight calculation. �高光。这增加了特殊的高光计算
Normal Mapped Specular. Again, this is a bit more expensive than Specular. �高光法线贴图。这比高光更昂贵一点
Parallax Normal mapped. This adds parallax normal-mapping calculation. �视差法线贴图。这增加了视差法线贴图计算
Parallax Normal Mapped Specular..�视差高光法线贴图。这增加了视差法线贴图和镜面高光计算

http://www.ceeger.com/Components/shader-NormalVertexLit.html
http://www.ceeger.com/Components/shader-Performance.html

2015-02-28 17:29:02 yuxikuo_1 阅读数 942

转载自:http://blog.csdn.net/onerain88/article/details/11713299

NGUI在Unity3D游戏开发中非常常用,而NGUI对于每一个UI场景,都是以一个UIRoot为UI游戏对象树的根的,那么这个UIRoot是起什么作用的呢?

先简单看一下UIRoot中的基本属性

UIRoot游戏对象的属性只有4个,分别是缩放规则,手动高度,最小高度和最大高度

而正是这4个属性,将影响整个UI场景中整体的缩放比例,当设置好这4个属性之后,UIRoot游戏对象的相对缩放值(LocalScale)将会生成并且不能被直接修改(NGUI中很多属性都是不能直接被修改的,这种控制是在UIRoot脚本中,通过设置[ExecuteInEditMode]做到的,其相对缩放值是根据UIRoot的4个属性计算出来的),那么这4个属性分别是什么含义呢?

(吐槽一下,也许这里的用户体验并不足够友好,因为Manual Height和Minimum Height, Maximum Height并不会同时起作用,如果能做到在选择Scaling Style时动态的切换,使用者也许能更清楚它们之间的关系)


1.Scaling Style (缩放类型)

这是一个简单的枚举变量,包括三个枚举值

  1. public enum Scaling  
  2.     {  
  3.         PixelPerfect,  
  4.         FixedSize,  
  5.         FixedSizeOnMobiles,  
  6.     }  
(FixedSize和FixedSizeOnMobiles类似,并且后者只添加了对ios和android平台的判断,所以前者可以替代后者使用)

这里只讨论PixelPerfect和FixedSize的区别,两者都是针对于所有在此UIRoot之下的UI组件而言的,也可以认为是在此UIRoot下,整个游戏屏幕的尺寸的缩放类型!


2.Manual Height和Minimum Height, Maximum Height (手动高度和最小高度,最大高度)

Manual Height和Minimum Height, Maximum Height不会同时对此UIRoot起作用,当选择Scaling Style为PixelPerfect时,我们需要设置Minimum Height, Maximum Height;而当Scaling Style为FixedSize或FixedSizeOnMobiles时,我们需要设置Manual Height。(这就是我前面吐槽的原因)


3.使用

(1)PexelPerfect和Minimum Height, Maximum Height

这个组合主要用于我们期望所有的UI纹理都“尽量”不进行缩放,所谓“尽量”的程度,则是取决于Minimum Height和Maximum Height,Minimum Height表示当设备分别率小于此设置值时,根据此设置值对UIRoot进行缩放;Maximum Height表示当设备分辨率大于此设置值时,根据此设置值对UIRoot进行缩放(UIRoot是UI游戏对象树的根,修改UIRoot的缩放,则会影响整棵UI树的缩放)

(2)FixedSize和Manul Height

这个组合主要用于我们期望所有的UI纹理都进行“合适”的缩放,所谓“合适”缩放的原则,则是根据Manual Height设置值,当设备分辨率的高度值不同于此设置值时,则根据其比例(即Manual Height / Screen Height)对整棵UI树的进行“等比”缩放(宽度的缩放比也是此比例值),这样,我们就可以做一套资源,在不同尺寸的分辨率最好的“不变形”的适配了

(3)交集

前面两组在什么情况下等同呢?

Manual Height == Minimum Height == Maximum Height 

推导过程,呵呵~~

具体可参考UIRoot中activeHeight属性和GetPixelSizeAdjustment的计算过程


4.这也许并不够

基于以上推到,当我们以1024x768为标准分辨率做一套UI资源(也就是选择FixedSize并且Manual Height=768),似乎可以满足百分之90以上的机型了,而为什么是1024x768呢?

既然我们已经容忍在除1024x768之外的其他设备上进行等比缩放了,那为什么不是960x640呢?

计算一下1024x768的宽高比=1.33,960x640的宽高比=1.5,这就是移动设备的分辨率比例的全部了吗?

当然不是,iphone5的比例就要大于1.5,还有各种奇葩的android设备呢,比如夏新的n828就是960x540,宽高比=1.78

那为什么以1024x768为标准呢?

因为1.33的宽高比,当我们的1024x768的资源到960x640的设备上时会有什么现象?

根据Manual Height / Screen Height的比例可知,我们需要缩放768 / 640 = 1.2倍,假设是一张1024x768的纹理,高度缩放1.2倍变为了640,宽度也要相应缩放1.2倍变为853(保证等比缩放不变形),也就是说1024x768的资源放到960x640上反而两边有了黑边,这是我们可以容忍的,我们可以做一个很大的背景或者拉伸,保证UI组件不变形即可,很多游戏都是这么做的,比如植物大战僵尸在iphone5和ipad上看到的背景视野并不一样大!

当放到夏新的机器上呢?

我们需要缩放768 / 540 = 1.4倍,宽度1024 / 1.4 = 731,这是可以的,只是看起来更怪一些,因为两边的黑边相对比例更大了(960 - 731=229的黑边区域)

而我表示android机器的分辨率奇葩到只有想不到,没有做不到的程度,也许宽高比1.7并不是终点,当遇到1.8之后,黑边的相对比例会更大。。。


5.问题又来了

假设我们的游戏类型更适合iphone手机玩,不太适合ipad,所以我希望能以960x640为标准做一套资源,可以吗?

我只能说不太可以,因为你要在设计UI组件的大小做限制了,为什么需要做限制?

假设我有一张纹理是960x640大小的,在iphone上铺满整屏,根据我们的设置(FixedSize和Manual Height=640),拿到1024x768的分辨率上,高度640 / 768 = 0.83,为了保证等比缩放,宽度960 / 0.83 = 1156,不幸的事情发生了,1156 > 1024,这个UI组件宽度超过了屏幕的宽度,被裁剪了。。。这是我们不能容忍的,或许你可以说我们尽量不做这种尺寸的UI,OK,你可以对UI尺寸加限制,但是当面对android那些奇葩的分辨率的时候,你会发现限制越来越大,这也许会让美术和策划疯掉!


6.解决方案

当我们花上一些时间去观察现在移动设备的分辨率时,虽然奇葩很多,但是还是有一些规律的,规律的在于宽高比而不在于具体尺寸,大体上划分一下宽高比在1.3,1.5,1.7的范围上的居多(基本是全部吧!)即便是再有1.2,1.8的比例也无妨。。。

NGUI为我们提供的方案只有以各种高度为衡量标准是不够的,我们应该加上一种以宽度为衡量标准的缩放类型

而对于UI资源的标准,我们选取960x640,宽高比为1.5

这样,当我们在兼容大于1.5的尺寸的时候,使用NGUI的现有方案;当我们在兼容小于1.5的尺寸的时候,使用以宽度为衡量标准

也就是说有一个类似Manual Width的属性,当小于1.5时,我们使用Manual Width / Screen Width得出整棵UI树的缩放比例!

这样做的好处是“黑边”区域不会太大,并且不需要对UI组件的大小做限制!


2016-10-17 11:12:13 k46023 阅读数 5420

前段时间整理的一篇关于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);
              else
                  uiRoot.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现在不是很熟,所以写的很简单,以后找时间在详细研究一下,再整理出来。

2016-09-12 13:57:27 c5138891 阅读数 8236

第一次写文章!

unity3d 开发项目适配问题处理,实现的结果是宽高比超出的部分相机直接裁掉留黑,如果要加背景可以再挂一个相机填补黑色,代码以横屏为例

using UnityEngine;

/// <summary>
/// 屏幕适配
/// </summary>
[RequireComponent(typeof(Camera))]
public class ScreenAdapt : MonoBehaviour
{
	public float screenHeight;
	public float screenWidth;

	void Start()
	{
		UpdateCamera ();
	}
	
	void UpdateCamera ()
	{
		screenHeight = Screen.height;
		screenWidth = Screen.width;

		Rect r = new Rect();
		if(screenHeight / screenWidth > 0.61f)//更方的屏幕 480*800
		{
			r.width = 1;
			r.height = (screenWidth * 0.61f) / screenHeight;
			r.x = 0;
			r.y = (1 - r.height) / 2f;
		}	
		else if(screenHeight / screenWidth < 0.56f)//更长的屏幕480*854
		{
			
			r.width = (screenHeight / 0.56f) / screenWidth;
			r.height = 1f;
			r.x = (1 - r.width) / 2f;
			r.y = 0;
		}
		else //在可适配区域不做处理480*800 - 480*854之间的
		{
			r.width = 1;
			r.height = 1;
			r.x = 0;
			r.y = 0f;
		}
		GetComponent<Camera>().rect = r;
	}
}

直接将脚本挂在需要适配的相机上即可,

原理就是修改的相机的视口


这样处理后,即可完美适配,建议pause/resume 后做一次刷新



http://blog.csdn.net/c5138891/article/details/52512881

Unity3D_屏幕适配

阅读数 138

没有更多推荐了,返回首页