我试图让我的UI元素工作,并为每个不同的分辨率保持不变。我在Canvas中添加了一个Canvas Scaler并使用这些设置进行播放,直到看完为止。
然后我尝试构建游戏并以几种不同的分辨率运行它以确认它是否正常工作。但是,Canvas Scaler似乎不起作用。
以上是一些随机分辨率,但是我的编辑器屏幕有多大,以及我用作参考分辨率的内容。这也是此特定Canvas http://prntscr.com/d1aggx的层次结构。当以640x480运行时几乎占据整个屏幕。我不知道为什么这不起作用。我已经阅读了大部分统一指南,但似乎都没有这个问题。
答案 0 :(得分:0)
好的,无论屏幕的大小如何,为了适应某些东西,你必须使用一个独立的坐标系统而不是Unity的绝对系统。 Unity的一个模型是View。视图是左上角的坐标0,0和右下角的1,1。创建一个处理它的基本Rect,如下所示。
using UnityEngine;
namespace SeaRisen.nGUI
{
public class RectAnchored
{
public float x, y, width, height;
public RectAnchored(float x, float y, float width, float height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public static implicit operator Rect(RectAnchored r)
{
return new Rect
{
x = r.x * Screen.width,
y = r.y * Screen.height,
width = r.width * Screen.width,
height = r.height * Screen.height
};
}
}
}
这里,我们采用普通的Rect浮点数,x,y坐标以及宽度和高度。但这些都在值[0..1]中。我没有把它夹住,所以如果需要的话,可以用动画在屏幕上和屏幕上进行补间。
以下是一个简单的脚本,它在屏幕的右下角创建一个按钮,并在屏幕增大或缩小时调整大小。
void MoveMe()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, -Vector3.up, out hit, float.MaxValue)
|| Physics.Raycast(transform.position, Vector3.up, out hit, float.MaxValue))
transform.position = hit.point + Vector3.up * 2;
}
void OnGUI()
{
if (GUI.Button(new RectAnchored(.9f, .9f, .1f, .1f), "Fix me"))
{
MoveMe();
}
}
X是右边的.9和顶部的Y .9,以及.1的宽度和高度,所以按钮是屏幕高度和宽度的1/10,位于底部的1/10屏幕。
由于每帧(或左右)都会渲染OnGUI,因此按钮rect会随着屏幕自动调整大小而更新。如果您使用Update()渲染窗口,那么在典型的UI中也是如此。
我希望这能解释我所说的绝对坐标之间的区别。设置在640x480中说上一个例子(使用绝对值),它就像new Rect(576, 432, 64, 48)
,它不会缩放。通过使用new RectAnchored(.9f, .9f, .1f, .1f)
并根据屏幕大小将其渲染到UI空间,然后它会自动缩放。