NGUI使用UIPanel和UIAnchor来管理UI元素,对屏幕适配已经支持得相当不错。但是由于屏幕尺寸的千奇百怪,开发过程中或多或少会碰到一些屏幕适配的问题。
微岛的HUD是基于iPhone 4的分辨率进行开发的,即限定了UIRoot上的UIPanel的Scaling Style为FixedSize, Manual Height为640。在做适配其他设备时还算比较顺利,主要碰到了一些小问题,在此谈谈。
先来看看市场上移动设备的分辨率情况,下面是友盟2014年7月份数据。
从数据可以看出,市场主流设备的长宽比最小的在1.33(即4/3),最大的在1.78(即16/9),围绕着这两个数值,就有许多可能会发生。
问题归类一:
1、部分高度为640的大窗口的长宽比达到1.5,超过了最小的1.33,导致在iPad等小比例设备上无法显示完整;
2、小比例设备上,左上角和右上角的UI在屏幕上方叠加在一起;
解决方案:
1、先试试能否加大窗口长宽比,方便适应
2、根据最小支持的长宽比值,适当加大UIPanel的Manual Height,达到总体缩小Panel元素的目的;
const int PANEL_HEIGHT_DEFAULT = 640; const float ADAPTE_ASPECTRATIO_MIN = 1.5f; //窗口支持的最小长宽比 //UIPanel使用此值做为Manual Height public static int GetPanelHeight() { int panelHeight = PANEL_HEIGHT_DEFAULT; float aspectRation = Screen.width * 1.0f / Screen.height; if (aspectRation < ADAPTE_ASPECTRATIO_MIN) { int minWidth = (int)(Screen.height * ADAPTE_ASPECTRATIO_MIN); panelHeight = PANEL_HEIGHT_DEFAULT * minWidth / Screen.width; } return panelHeight; } public static int GetPanelWidth() { return GetPanelHeight() * Screen.width / Screen.height; }
问题归类二:
3、一张底图做背景的场景(如启动界面、登录背景等),会出现显示不全或者有空白的地方;
解决方法:
1、准备三张图,尺寸分别为960x640, 1136x640,1024x768,即分别为iPhone4, iPhone5, iPad 1的,放到Resources/Texture目录下,分别命名为splash_4to3@ldpi.png, splash_3to2@xhdpi.png和splash_16to9@xhdpi.png;
2、根据屏幕长宽比动态调节UIPanel和UI2DSprite的宽度和高度,代码如下;
const float ADAPTE_ASPECTRATIO_4TO3 = 1.334f; const float ADAPTE_ASPECTRATIO_3TO2 = 1.5f; const float ADAPTE_ASPECTRATIO_16TO9 = 1.77f; public UI2DSprite splashSprite; int width = Screen.width; int height = Screen.height; float aspectRation = Screen.width * 1.0f / Screen.height; string splashTextureName = null; if (aspectRation <= ADAPTE_ASPECTRATIO_4TO3) { splashTextureName = @"Textures/splash_4to3@ldpi"; } else if (aspectRation <= ADAPTE_ASPECTRATIO_3TO2) { splashTextureName = @"Textures/splash_3to2@xhdpi"; } else if (aspectRation <= ADAPTE_ASPECTRATIO_16TO9) { splashTextureName = @"Textures/splash_16to9@xhdpi"; } else { splashTextureName = @"Textures/splash_16to9@xhdpi"; } Sprite splashTexture = (Sprite)Resources.Load(splashTextureName, typeof(Sprite)); if(splashTexture != null) { int textureWidth = (int)splashTexture.textureRect.width; int textureHeight = (int)splashTexture.textureRect.height; splashSprite.sprite2D = splashTexture; if(Screen.height < textureHeight) { textureWidth = textureWidth * Screen.height / textureHeight; textureHeight = Screen.height; } if (aspectRation > ADAPTE_ASPECTRATIO_16TO9) { textureWidth = Screen.width; textureHeight = textureWidth * 640 / 1136; } root.manualHeight = textureHeight; splashSprite.width = textureWidth; splashSprite.height = textureHeight; } else { Debug.LogWarning(string.Format("No Sprite At Resource Path {0} Found!", splashTextureName)); }
问题归类三:
4、部分遮罩不能覆盖住整个屏幕:
解决方法:
使用问题一的解决方法,用GetPanelHeight()和GetPanelWidth()返回的值 来设置遮罩的长宽值;