转载链接:
http://forum.exceedu.com/forum/forum.php?mod=viewthread&tid=33090&extra=page%3D1
概述
UIRoot总是放在NGUI UI层级的最上层。它用来使UI的缩放变得更容易。widget通常使用的是以像素为单位的坐标,但是一个800*400(dimensions的值)的widget会占用800*400个单位(Unity中的单位),这相当大。UIRoot通过屏幕高度的反比来进行缩放,因此widgets都会很小,并且操作起来更容易。
UIRoot有几种缩放方式。最常见的就是PixelPerfect。这种方式下,你的UI一直都是以像素为基础,一个300*200的widget在屏幕上永远占用300*200像素。这就意味着,你的UI在低分辨率的机器上会显得非常大,在高分辨率的机器上就会显得很小。这个设置就是一直保持你的UI清晰。
FixedSize是一个和它功能正好相反的设置。当UIRoot用了这个选项,你的屏幕永远都会保持NGUI所关心的尺寸,不管你的实际屏幕是多大。就是说一个300*200的widget占用了你1920*1080的25%的屏幕,那么当分辨率降低到1280*720的时候,它同样占用25%的屏幕。如果你不介意你的UI看起来像是不同的尺寸,也不关心是否清晰(就是可能一个小的UI被拉伸很大),那么选择这个选项。选择它的时候,不要忘记设置Manual Height。
这个占的百分比就是通过widget的尺寸和当前你设置的Manual的尺寸而算出来,所以当你移植到不同的移动设备时,它会根据这个占比和移动设备的实际分辨率进行运算,然后算出显示的实际像素大小。
FixedSizeOnMobile是前两种的组合。选择这个选项后,会在pc或者mac等桌面设备上用“PixelPerfect”,在移动设备上用“FixedSize”。
如果你没有选择Fixed Size选项,那就要设置Minimum和Maximum Height的值。这些值让你的虚拟屏幕看起来在合理范围。比如选择了Pixel Perfect方式,Minimum Height设置为720,那么当有玩家把你的程序运行在800*600(高度是600,小于Minimun Height)的设备上时,你UI的行为就和设置了“Fixed Size”模式、Manual Height值设为720的时候一样。
这个Minimum和Maximum Height用于你对实际的屏幕尺寸进行限制,如果实际的屏幕尺寸小于Minimum,那么就相当于设置了“Fixed Size”模式、Manual Height值设为Minimum的时候一样,同理,如果屏幕尺寸超过了Maximum,那也相当于设置了“Fixed Size”模式、Manual Height值设为Maximum的时候一样。
小贴士
UIRoot以2/ScreenHeight的值进行缩放。ScreenHeight可能是实际的屏幕高度(Pixel Perfect),也可能是manual height(Fixed Size)。这样做的目的是使渲染UI的camera的Orthographic Size的值一直使用1。
如果你不需要UIRoot的自动缩放功能,直接去掉这个组建。
这个UIRoot是这个意思,就是为了保持相机的Size是1,所以在UIRoot的Transform组件里会将缩放比例设置成分辨率高度的一半的倒数,比如针对iPad的屏幕1024*768分辨率,为了保持Size是1,缩放UI的Root为该值的倒数,比如在iPad上获得完美尺寸你需要设置Root的缩放到1/384或者0.002604167。
再来看看UIRoot这个脚本:
/// <summary>
/// UI Root's active height, based on the size of the screen.
/// </summary>
public int activeHeight
{
get
{
int height = Mathf.Max(2, Screen.height);
if (scalingStyle == Scaling.FixedSize) return manualHeight;
#if UNITY_IPHONE || UNITY_ANDROID
if (scalingStyle == Scaling.FixedSizeOnMobiles)
return manualHeight;
#endif
if (height < minimumHeight) return minimumHeight;
if (height > maximumHeight) return maximumHeight;
return height;
}
}
protected virtual void Start ()
{
UIOrthoCamera oc = GetComponentInChildren<UIOrthoCamera>();
if (oc != null)
{
Debug.LogWarning("UIRoot should not be active at the same time as UIOrthoCamera. Disabling UIOrthoCamera.", oc);
Camera cam = oc.gameObject.GetComponent<Camera>();
oc.enabled = false;
if (cam != null) cam.orthographicSize = 1f;
}
else Update();
}
void Update ()
{
if (mTrans != null)
{
float calcActiveHeight = activeHeight;
if (calcActiveHeight > 0f )
{
float size = 2f / calcActiveHeight;
Vector3 ls = mTrans.localScale;
if (!(Mathf.Abs(ls.x - size) <= float.Epsilon) ||
!(Mathf.Abs(ls.y - size) <= float.Epsilon) ||
!(Mathf.Abs(ls.z - size) <= float.Epsilon))
{
mTrans.localScale = new Vector3(size, size, size);
}
}
}
}
可以清楚的看出,在初始化时将缩放比例设置成了屏幕分辨率高度一半的倒数。