如果在 Unity 的 Game view 使用 Free Asspect 观察画面时,任意的拉动视窗边缘去调整画面比例,可以发现 UGUI 本身是并不会移动位置或缩放大小,如果将 320x480 变为 480x320,就有可能使 UI 被画面边缘切掉,这时候 Anchors 就能发挥很大的用处,使得 UI 图片或按钮等元素都能跟随画面比例的改变而变更其宽高大小,但其美中不足的是文字并不会因此跟随改变大小,当然,如果文字有勾选 Best Fit 的话,也会有自动变更 Size 的效果,只是,按钮、图片等 UI 元素跟随画面比例改变,也改变了本身的宽高比例,但文字却只是改变 Font Size,所以,当画面比例改变了,图片变形了,文字并未跟着变形,那么文字与其他 UI 之间的距离或是按钮边缘与按钮内的文字的间隙就可能会发生奇怪的变化,这些都是我们所不希望看到的,所以,最好的状况应该是,当画面比例改变了,UI 的图片、文字、按钮等文字都能维持原本的长宽比例自动缩放大小及位置。
当在场景中建立第一个 UGUI 的游戏物件时,一定会先自动建立 Canvas 的游戏物件,在这个物件中,预设配置了 Canvas、Canvas Scaler、Graphic Raycaster 这三个 Component,其中的 Canvas Scaler 正是用来控制 UGUI 整体的缩放,所以只要依照以下步骤,就能达到最基本的依照原比例调整 UI 的目的:
- 让所有的 UI 的 Anchors 维持在预设值(0.5)。
- 将 Canvas Scaler 的 Ui Scale Mode 栏位设置为 Scale With Screen Size。
- 在 Reference Resolution 栏位输入预设尺寸的宽(X)、高(Y)。
- Screen Match Mode 栏位选择 Match Width Or Height。
- 如果画面为横向,Match 栏位选输入 0,如果画面为纵向,Match 栏位输入 1。
如此,当画面从纵向转为横向,GUI 就会自动维持原比例调整其大小及位置。
但是,这是在比例相同直接横向转纵向时才会如此理想,当遇到比例不同的画面,例如原本是 iPhone 4 的 640x960 设计的 UI 佈局,遇上了 iPhone 5 的 640x1136 画面,就会发生左右两边被切掉的情形。
这时我们就必须将 Canvas 游戏物件的 Canvas Scaler componet 的 Match 栏位改为 0,使其 UI 依照原本比例缩放调整到画面内。
为了应对可能遇到各种未知的画面比例(特别是 Android ),我们可以为 Canvas 挂上以下这个脚本来自动调整 Canvas Scaler 组件的 Match属性。
void Awake(){
CanvasScaler canvasScaler = GetComponent<CanvasScaler>();
float screenWidthScale = Screen.width / canvasScaler.referenceResolution.x;
float screenHeightScale = Screen.height / canvasScaler.referenceResolution.y;
canvasScaler.matchWidthOrHeight = screenWidthScale > screenHeightScale ? 1 : 0;
}
完成以上的工作,将来在 UI 制作上就会轻松很多,如果没有特殊需求,基本上不需要动到 UI 的 Anchors 值,大部份都只是单纯的调整 UI 大小及位置就行了,面对各种画面比例,也将维持原设计的佈局自动调整,另外,如果需要制作 UI 的动态缩放、位移等等使画面更生动的话,以变更其 Local space 的数值为主,那么比例缩放的部分都不需要特别去考虑,Canvas Scaler 会帮我们处理。
不过,有一个例外,目前是无法使用此办法解决的,就是当 UI 文字使用了 Rich Text 的 Size 标签去指定文字大小时,文字的大小是不会受到 Canvas Scaler 影响的,它是绝对的文字 Size,这一点要特别注意。