Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中

当我们开发游戏时,如果是开发手机游戏,屏幕窗口的比例是固定的,不会说在运行时改变的。

但是,PC端的游戏就不一定,我希望它能被用户随意拉扯,但完整的内容还是能显示出来,这里我直接放例子:

Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中

请注意黑色的部分,可以看到,不管窗口被如何拉扯,游戏的内容还是被完整的显示了出来,窗口能被随意的拉伸,用户的体验更好。

那么来讲一讲Unity如何实现这种效果:

首先是UGUI,UGUI实现有现成的方案,可以通过设置Canvas 和 Canvas Scaler 来适配窗口

Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中

关键在于Screen Match Mode 的 Expand(扩展)效果,当我们拉扯窗口时,无论怎样UI都会完整的显示。

演示下效果(效果可能不太直观,见谅):

Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中

但问题来了,UI是能适配屏幕的,但是游戏世界是不会适配的。(这句话有歧义,实际是游戏世界的大小是不变的,变的是摄像机的视角)

所以接下来引出问题的关键:

首先,创建一个Sprite,用100*100的纯白图片作为sprite,将Sprite的大小放大为宽16单位,高9单位(符合屏幕比例):

将摄像机的Y坐标设为0,size设为4.5(事前准备),当然这里摄像机为正交类型

Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中

Camera 的size是一个很重要的属性,它决定了摄像机的高度的一半对应游戏世界的高度:比如说这里size为4.5,size*2 = 9 个单位,对应了上图。在这里,游戏世界被完整的呈现在屏幕里。

size对应的是摄像机的高度,所以摄像机是有高度适配的,它工作的效果如下:

Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中

就算你把屏幕的高度拉的很低,游戏的内容始终会完整的显示在屏幕中。但问题来了,size针对高度,但它不针对宽度,这就有一个问题,比如说我把宽度拉的很小:

游戏的内容并没有完整的显示在屏幕上(右图白色的框对应屏幕大小,灰色对应游戏的对象  大小19:6)

Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中

这时候想要让游戏世界完整的显示,显然需要让Camera的size变大,让摄像头屏幕大小包含游戏对象。

脚本 CameraAdjust.cs

 1 using UnityEngine;
2
3 [ExecuteInEditMode]
4 public class CameraAdjust : MonoBehaviour
5 {
6 private const float DEFAULT_RATIO = 16f / 9f;
7 private int m_ScreenWidth;
8 private const float DEFAULT_SIZE = 4.5f;
9
10 private void Start()
11 {
12 m_ScreenWidth = Screen.width;
13 }
14
15 private void LateUpdate()
16 {
17 if (m_ScreenWidth != Screen.width)
18 {
19 m_ScreenWidth = Screen.width;
20
21 float width = Screen.width;
22 float height = Screen.height;
23 float ratio = width / height;
24 if (ratio > DEFAULT_RATIO)
25 {
26 if (Camera.main.orthographicSize != DEFAULT_SIZE)
27 Camera.main.orthographicSize = DEFAULT_SIZE;
28 }
29 else
30 {
31 Camera.main.orthographicSize = DEFAULT_SIZE * (DEFAULT_RATIO) / (width / height);
32 }
33 }
34 }
35 }

效果如下:

Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中

这里有两个需要注意的点:

1.Screen.width 和 height 的是int变量,运算时需要转化为float

2.在调试代码时请谨慎使用 [ExecuteInEditMode],在开发时请务必备份场景中的内容。

上一篇:ASP.NET MVC SignalR(1):背景


下一篇:spring-mvc实现模拟数据到网页展示过程代码