ngui 自适应和对齐
本文主要介绍 NGUI 的自适应和对齐相关内容。由于我在实际使用中未达到理想效果,后在其他博客上获取到相关知识,现分享给大家。
一、自适应:使用 UIRoot 的 ManualHeight
我常向在屏幕适应方面遇到问题的人推荐使用 UIRoot 的 ManualHeight 方法。下面先提供三张截图,展示不同分辨率下的效果,你可以看看是否符合需求。对于屏幕旁边空白的部分,你需要与策划、美术人员沟通,使用一些背景来遮挡。
不同分辨率下的效果
- 正常开发分辨率下:界面显示符合预期布局。
- 看起来较细的分辨率:可能出现两侧空白等情况。
- 看起来较宽的分辨率:也可能存在上下空白等问题。
使用注意事项
- 确定开发分辨率:与策划人员共同制定开发时的分辨率,这一点至关重要,要确保所有 UI 元素都在相同的分辨率下制作,以保证 UI 的一致性和准确性。
- 挂载脚本并修改设置:将以下脚本挂载在 UIRoot 上,同时把 UIRoot 的 Scaling Style 修改为 FixedSize。
- 设置开发高宽:脚本中的
aspectRatioHeight和aspectRatioWidth分别对应开发时的高和宽。 - 调整 ManualHeight:每个 UIRoot 都需要将 ManualHeight 调整到与策划制定的高度一致。
- 调整 Unity3D 窗口分辨率:在 Unity3D 的 Game 窗口中,将分辨率调整到相应的开发分辨率。
脚本代码
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(UIRoot))]
public class SZUIRootScale : MonoBehaviour
{
public int aspectRatioHeight;
public int aspectRatioWidth;
public bool runOnlyOnce = false;
private UIRoot mRoot;
private bool mStarted = false;
void Awake()
{
UICamera.onScreenResize += ScreenSizeChanged;
}
void OnDestroy()
{
UICamera.onScreenResize -= ScreenSizeChanged;
}
void Start()
{
mRoot = NGUITools.FindInParents<UIRoot>(this.gameObject);
mRoot.scalingStyle = UIRoot.Scaling.FixedSize;
this.Update();
mStarted = true;
}
void ScreenSizeChanged()
{
if (mStarted && runOnlyOnce)
{
this.Update();
}
}
void Update()
{
float defaultAspectRatio = aspectRatioWidth * 1f / aspectRatioHeight;
float currentAspectRatio = Screen.width * 1f / Screen.height;
if (defaultAspectRatio > currentAspectRatio)
{
int horizontalManualHeight = Mathf.FloorToInt(aspectRatioWidth / currentAspectRatio);
mRoot.manualHeight = horizontalManualHeight;
}
else
{
mRoot.manualHeight = aspectRatioHeight;
}
if (runOnlyOnce && Application.isPlaying)
{
this.enabled = false;
}
}
}
(感谢成都 - 大强提供以上代码。注意:UICamera.onScreenResize 是 3.0+ 版本的,如果报错请删除即可)
二、UI 部件对齐
对齐方式
对于各种对齐的 UI 部件,如图所示的对齐方式,简单的做法是设置 anchor。在 NGUI 的例子中,通常是对 UI Root 来设置 anchor。但如果我们将 UI 制作成 prefab 进行保存,并在运行时实时实例化加载,这些 UI 部件就会自动失去与 UI Root 的 anchor 关系。
解决方案
其实解决方法很简单,只要让这些 UI 部件针对本 UI 最外层的 UISprite 来设置 anchor,然后在加载后实时将 target 改为 UI Root 即可。