Unity2D中摄像机镜头的尺寸决定了我们实际看到多少

Unity2D中摄像机镜头的尺寸决定了我们实际看到多少

---------------------------------------正式出发分割线------ ----------------------------------

我们先解释一下一些基本概念:

1.宽高比=屏幕宽度/屏幕高度

2、Unity2D中摄像头镜头的大小决定了我们实际看到游戏内容的多少。 在编辑器中,我们可以通过调整相机Camera的orthographicSize属性值来调整相机的大小。 如下图所示,当相机orthographicSize属性值等于当前屏幕高度单位的一半时,相机尺寸正好等于屏幕尺寸。 注意,这里所说的是屏幕单位高度的一半。 该值通过像素与单位的比率(即 Pixels To Units)转换。 Unity2D中这个比例的默认值为100,即100个像素等于1个单位。 如果我们的游戏画面高是640像素,那么实际换算后的单位高度就是6.4个单位。 当我们相机的orthographicSize值为3.2时,相机尺寸正好等于屏幕尺寸。

分辨率适配什么意思_unity 分辨率适配_分辨率适配常用方法前端

分辨率适配常用方法前端_分辨率适配什么意思_unity 分辨率适配

(您可以通过该选项调整每张图像的像素单元比例)

看到这里,你可能会问,相机的高度只能在Unity编辑器中直接调整unity 分辨率适配,那么相机的宽度是如何确定的呢? 答案就是我们上面提到的屏幕长宽比。 Unity会根据当前屏幕的实际长宽比和相机的orthographicSize值来计算相机的宽度,即:

实际相机宽度 = 相机正交尺寸* 2 * 屏幕纵横比

也就是说

相机实际宽度=相机高度*屏幕长宽比

让我举一个例子。 iPhone 4的屏幕像素为640*960,长宽比为2:3。 假设 Pixels To Units 值为 100,那么如果相机高度尺寸值设置为 4.8,那么根据公式 6.4 计算出相机的实际宽度,这正是屏幕的单位宽度。

---------------------------------------逐渐变好的分割线---- -----------------------------------------

好了,讲完上面的内容我们就知道为什么我们的游戏在不同屏幕分辨率的设备上显示效果会不一样了。

不同的屏幕分辨率和相同的相机orthographicSize值会产生不同的相机尺寸,不同的相机尺寸会导致实际显示的游戏内容存在差异。

接下来我再提出两个概念,方便后续解释:

1、游戏有效内容是指游戏中必须完整显示在屏幕上的内容;

2、实际游戏内容是指所有游戏内容,包括有效内容和主要为适应多种分辨率或其他不重要目的而添加的内容。

我们的开发一般选择以固定的设计分辨率进行,比如常用的iOS竖屏游戏设计分辨率为640*960。 我们就以此设计方案为例。 通常,设计分辨率大小就是我们游戏有效内容的大小。

使用此分辨率,我们将相机的 orthographicSize 值设置为 4.8。 假设我们不做任何多分辨率适配处理,这样我们游戏的有效内容区域和实际内容区域大小是一样的,都是6.4*9.6(已经做了像素到单位的转换,下同),让这个游戏运行一下,看看在iPhone 5设备上(即屏幕为640*1136)会发生什么。

为了更好的解释,让我们首先设置变量:

游戏有效内容尺寸为gameValidContentSize

游戏实际内容尺寸为gameContentSize 摄像机尺寸为cameraSize 实际屏幕尺寸为screenSize 屏幕宽高比为aspectRatio

然后开始计算:

orthographicSize = 4.8
aspectRatio = 640/1136 = 9/16
cameraSize.height = 摄像机orthographicSize * 2 = 4.8 * 2 = 9.6
cameraSize.width = cameraSize.height * aspectRatio = 9.6 * 9 /16 = 5.4

根据计算得出实际摄像头宽度为5.4,游戏有效内容宽度为6.4。 相机宽度小于游戏有效内容宽度,即cameraSize.width < gameValidContentSize.width = gameContentSize.width。 这时,游戏内容就被镜头剪切了!

下面以我做的一个小游戏为例,我们可以更清楚地看到这个问题:

第一张图是在640*960设备上运行时的效果,一切正常。 第二张图是在640*1136设备上运行的效果。 可以看到游戏内容被明显删减,右上角的按钮几乎消失了。

unity 分辨率适配_分辨率适配常用方法前端_分辨率适配什么意思

unity 分辨率适配_分辨率适配常用方法前端_分辨率适配什么意思

如何解决这个问题呢? 最直接的想法就是,如果我们的游戏在640*1136屏幕的设备上,摄像头宽度保持6.4,那肯定不会被剪掉。 为了做到这一点,我们必须在运行时调整相机的 orthographicSize 值。 方法很简单,用上面提到的公式即可:

aspectRatio = 9/16
为了使cameraSize.width = 6.4,我们计算
cameraSize.height = cameraSize.width/aspectRatio = 6.4 * 16 / 9 (因为除不尽,后面就不继续写了)
camera的orthographicSize = cameraSize.height / 2 约=5.69

我们再次运行游戏,动态修改相机的orthographicSize值为5.69。 我们可以看到:

分辨率适配常用方法前端_分辨率适配什么意思_unity 分辨率适配

宽幅显示完全,但顶部和底部出现“黑边”(这里是蓝边,哈哈)。 这是因为相机的高度已经大于游戏内容的高度,所以自然会出现没有内容的区域,即“黑边框”。 为了解决这个问题,我们需要给游戏添加上下边框。 一种方法是直接添加一张与黑框大小相同的图片,但是还有更简单的方法,直接放大游戏背景覆盖黑框! 这个游戏比较简单。 我们使用这个简单的方法。 我们将游戏背景放大到1.3倍程序开发,如下图:

分辨率适配常用方法前端_分辨率适配什么意思_unity 分辨率适配

好的! 现在我们的游戏看起来正常了,已经适配iPhone5了。

注意到此时我们游戏的有效内容区域不再等于实际内容区域,我们放大了背景图片,这实际上给游戏添加了一个外边缘。 如图所示,白框内的区域为有效内容区域,白框外的区域为无效内容区域。 整体实际游戏内容区域大于有效内容区域。

unity 分辨率适配_分辨率适配什么意思_分辨率适配常用方法前端

----------------------------------------------------最终结论的分割线--- ---------------------------------------------------------

根据以上解决分辨率问题的过程音乐音效,我们可以得出,实际的分辨率适配问题与三个尺寸有关,分别是:摄像头尺寸、游戏内容尺寸(包括有效内容尺寸和无效内容尺寸)和实际屏幕尺寸。 为了能够显示我们需要的有效内容而不显示黑边框,我们必须保证:

摄像头尺寸必须小于或等于游戏实际内容尺寸,且必须大于或等于游戏有效内容尺寸。 如下图所示,蓝色线框代表相机的尺寸。 只要保证蓝框在白框之外,就可以在画面内正确显示游戏内容。

unity 分辨率适配_分辨率适配常用方法前端_分辨率适配什么意思

只要我们能够保证以上几点,我们的游戏就可以处理几乎所有的屏幕分辨率。

按照这个方案,归根结底,解决屏幕分辨率适配问题,实际上就是解决如何将游戏摄像头的尺寸限制在给定范围内的问题。

总结一下,步骤是:首先需要确定游戏的有效内容区域和实际内容区域; 然后,当游戏开始时,根据实际屏幕宽高比将相机尺寸调整为适合您游戏的尺寸。

----------------------------------------------------最后的分割线----- - ---------------------------------------

最近写了很多小游戏,使用这个方案一劳永逸地解决了多分辨率适配的问题,特别是Android设备适配的问题。 这种方法的优点是只要懂了就很容易操作。 另一方面,它与缩放游戏内容不同。 这种方法保证了游戏内容的真实性。 当然unity 分辨率适配,也可能有缺点。 我暂时能想到的是,对于一些依赖相机进行效果或操作的游戏来说,改变相机的大小可能会产生一些影响。 目前这方面的经验比较少,希望这个解决方案能够在未来不断完善。

最后我写了一个简单的脚本来调整orthographicSize值,保证相机的宽度值不会小于游戏的有效内容宽度。 有效内容大小为6.4*9.6。 这个脚本只要挂在游戏的Camera上就可以生效。

1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class GameCamera : MonoBehaviour {
 5 
 6     float devHeight = 9.6f;
 7     float devWidth = 6.4f;
 8 
 9     // Use this for initialization
10     void Start () {
11     
12         float screenHeight = Screen.height;
13 
14         Debug.Log ("screenHeight = " + screenHeight);
15 
16         //this.GetComponent().orthographicSize = screenHeight / 200.0f;
17 
18         float orthographicSize = this.GetComponent().orthographicSize;
19 
20         float aspectRatio = Screen.width * 1.0f / Screen.height;
21 
22         float cameraWidth = orthographicSize * 2 * aspectRatio;
23 
24         Debug.Log ("cameraWidth = " + cameraWidth);
25 
26         if (cameraWidth < devWidth)
27         {
28             orthographicSize = devWidth / (2 * aspectRatio);
29             Debug.Log ("new orthographicSize = " + orthographicSize);
30             this.GetComponent().orthographicSize = orthographicSize;
31         }
32 
33     }
34     
35     // Update is called once per frame
36     void Update () {
37     
38     }
39 }

文章来源:https://my.oschina.net/u/4279383/blog/3717646