被NGUI自适应苦苦困扰,终于下定决心好好看,看了许多大神的心得,这是本人的一点总结。
主要参考了两位大神写的
http://www.cnblogs.com/liujidong/p/5650305.html 晓东大神
http://www.xuanyusong.com/archives/2536 雨松大神
首先呢,了解一下NGUI的的两个容器组件 UI Panel和UI Widget。
UI Panel相对于UI Widget的父物体一样,一个UI Panel包含多个UI Widget
1.UI Panel
UIPanel用来收集和管理它下面所有widget的组件。通过widget的geometry创建实际的draw call(与优化有关的东西,还不太了解)。没有panel所有东西都不能够被渲染出来,你可以把UIPanel当做Renderer。
所有panel都有一个Depth值,会影响所有它包含的widget。如果你的UI有很多窗口,那么最好每个窗口有一个panel。Panel上的depth权重会远远高于每一个widget的depth权重,所以保证panel不要使用同样的depth。如果使用同样的depth在panel上,那么draw call会被自动拆分来保证渲染顺序,所以会增加更多的draw call。
Manual Height:这个属性就比较重要的,因为我们的自适应屏幕,原理就是根据Screen.width 和Screen.height来动态的计算它的实际高度,动态的修改这个值。
Min/Max inum Height:这就是支持的最大高度,和最小高度一般都是 640 到 1536。
这个占的百分比就是通过widget的尺寸和当前你设置的Manual的尺寸而算出来,所以当你移植到不同的移动设备时,它会根据这个占比和移动设备的实际分辨率进行运算,然后算出显示的实际像素大小。即Scaling Style指定为FixedSize或FixedSizeOnMobiles,则缩放只以Manual Height为参考,屏幕分辨率的高度值不同于此设置值时,则根据其比例(即Screen Height / Manual Height)对整棵UI树的进行“等比”缩放(宽度的缩放比也是此比例值)。
3: 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的时候一样。(感觉这个还是很好的,在介于Minimum与Maximm之间时,UI元素的大小不会改变,一旦小于Minimum时就相当与Fixed等比例缩小,大于Maximum相当于Fixed等比例放大)
对于UI界面移植到其他的不同分辨率的屏幕上,只能用脚本动态的改变Manual Height的大小才能使界面完全显示出来,那么这样的话会出现黑边的情况,所以可以用Anchor使图片拉伸以覆盖黑边,但是这要你不介意图片拉伸的情况下。
例如在960 * 640的屏幕下,由于Manual Height = 720,所以720放到640的高度下需要缩放640/720 = 8/9, 由于UI是按照1280*720的尺寸设计的,所以UI的宽度缩为1280 * 8/9 = 1137.7,明显960的宽度根本放不下,所以我们要继续更改缩放系数,使其
能够在960的宽度下完全显示,而这个缩放系数是根据屏幕尺寸和Manual Height算出来的,所以我们只需要动态的去计算Manual Height,就可以很好的将UI整体放进屏幕中了。
动态改变Manual Height的脚本如下
using UnityEngine;
using System.Collections;
public class UIAdapter : MonoBehaviour {
public int ManualWidth = 1280;
public int ManualHeight = 720;
void Awake ()
{
AdaptiveUI();
}
private void AdaptiveUI()
{
UIRoot uiRoot = GetComponent();
if (uiRoot != null)
{
if (System.Convert.ToSingle(Screen.height) / Screen.width > System.Convert.ToSingle(ManualHeight) / ManualWidth)
uiRoot.manualHeight = Mathf.RoundToInt(System.Convert.ToSingle(ManualWidth) / Screen.width * Screen.height);
else
uiRoot.manualHeight = ManualHeight;
}
}
}
总的来说呢,UI界面的做自适应还是可以完美解决的 Scaling Style+Anchor+Manua Height动态改变脚本应该是没问题的。
新人投稿,多多包涵。