NGUI HUD屏幕适配

2015年08月05日 13:37 0 点赞 0 评论 更新于 2025-11-21 15:35

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 元素叠加:在小比例设备上,左上角和右上角的 UI 在屏幕上方叠加在一起。

解决方案

  1. 尝试加大窗口的长宽比,以提高其适应性。
  2. 根据最小支持的长宽比值,适当加大 UIPanel 的 Manual Height,从而总体缩小 Panel 元素。以下是实现该功能的 C# 代码:
    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; }


### 问题归类二
**背景图显示问题**:在以一张底图作为背景的场景(如启动界面、登录背景等)中,会出现显示不全或者有空白的情况。

#### 解决方法
1. 准备三张不同尺寸的图片,分别为 960x640(对应 iPhone4)、1136x640(对应 iPhone5)、1024x768(对应 iPad 1),将它们放到 Resources/Texture 目录下,并分别命名为 splash_4to3@ldpi.png、splash_3to2@xhdpi.png 和 splash_16to9@xhdpi.png。
2. 根据屏幕长宽比动态调节 UIPanel 和 UI2DSprite 的宽度和高度,以下是实现该功能的 C# 代码:

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)); }


### 问题归类三
**遮罩覆盖不全**:部分遮罩不能覆盖住整个屏幕。

#### 解决方法
使用问题一的解决方法,通过 `GetPanelHeight()` 和 `GetPanelWidth()` 返回的值来设置遮罩的长宽值。

综上所述,通过上述针对不同问题的解决方案,可以有效解决 NGUI HUD 开发过程中的屏幕适配问题。

作者信息

洞悉

洞悉

共发布了 3994 篇文章