目前市面上的刘海屏层出不穷,作为全面屏的过渡设计。在市场上也是占有一定份额,那么在开发上,就要对此类产品做一定的适配。
解决方案:
利用UIPanel进行调整对业务中被刘海遮挡的UI进行整体偏移,这样的好处是因为被遮挡部分的无非是极少数在刘海区域的UI,而对角边和中间界面的并没有影响,所以对游戏UI整体显示进行偏移显然会对玩家有不好的体验,所以拆分为业务逻辑,需要的自行进行调用是比较理想的方法。
在UIPanel中的Clipping中有一个constrain but don’t clip的选项,顾名思义就是约束但是不进行裁剪。
在业务模块中使用这个便可以与UI Root中的UIPanel中划分出一个空区域作为刘海部分。然后在设计UI时将对需要适配的部件的锚点对此pnale的边进行绑定,就可以简单的实现偏移
计算偏移后的UIPanel的Rect大小:
private Rect CalculateNGUIRect()
{
var edgeInset = GetPhoneEdgeInset();//得到手机型号的屏幕参数
if (edgeInset == null)
{
return null;
}
var root = GameObject.Find("UI Root").GetComponent<UIRoot>();//这里需要得到根节点,这里偷懒直接Find
var pixelSizeAdjustment = root.pixelSizeAdjustment;
var screen = NGUITools.screenSize;
var widthScale = 1f;
var heightScale = 1f;
#if UNITY_EDITOR
widthScale = screen.x / edgeInset.Width;
heightScale = screen.y / edgeInset.Height;
#endif
var width = screen.x - (edgeInset.Left - edgeInset.Right) * widthScale;
var height = screen.y - (edgeInset.Top - edgeInset.Bottom) * heightScale;
var rect = new Rect
{
Width = width * pixelSizeAdjustment,
Height = height * pixelSizeAdjustment,
X = (edgeInset.Left - edgeInset.Right) * pixelSizeAdjustment / 2 * widthScale,
Y = (edgeInset.Bottom - edgeInset.Top) * pixelSizeAdjustment / 2 * heightScale,
Left = edgeInset.Left * pixelSizeAdjustment * widthScale,
Bottom = edgeInset.Bottom * pixelSizeAdjustment * heightScale,
Right = edgeInset.Right * pixelSizeAdjustment * widthScale,
Top = edgeInset.Top * pixelSizeAdjustment * heightScale,
ScreenWidth = edgeInset.Width * pixelSizeAdjustment * widthScale,
ScreenHeight = edgeInset.Height * pixelSizeAdjustment * heightScale,
};
return rect;
}
更新位置:
public void ResizePanel(GameObject go, bool clip = false)
{
if (IsNeedResize())
{
var rect = GetRect();
var panel = go.GetComponentInChildren<UIPanel>();
if (panel != null)
{
panel.clipping = clip ? UIDrawCall.Clipping.SoftClip : UIDrawCall.Clipping.ConstrainButDontClip;
panel.SetRect(rect.X, rect.Y, rect.Width, rect.Height);
var rects = go.GetComponentsInChildren<UIRect>(true);
var count = rects.Length;
for (int i = 0; i < count; i++)
{
rects[i].UpdateAnchors();
}
}
}
}
然后在需要适配的模块上增加监听方法即可:
void Start ()
{
ScreenResizeManager.Instance.OnOrientationChanged += ResizeWindow;
ResizeWindow();
}
void OnDestroy()
{
ScreenResizeManager.Instance.OnOrientationChanged -= ResizeWindow;
}
private void ResizeWindow()
{
if(ScreenResizeManager.Instance.IsNeedResize())
ScreenResizeManager.Instance.ResizePanel(this.gameObject);
}
回到编辑器,新建一个UIPanel对象挂上上面的脚本,然后创建两个UISprite在下面,分别将锚点固定在两边。
调出测试工具,设定好型号和朝向。
运行:
gifhub:https://github.com/NICKS-CHN/-unity-iPhoneX-Adaptation
idea by http://www.cilugame.com/