【Unity】微信小游戏UI适配
Unity 发布微信小游戏适配刘海屏或者摄像头 等安全区域
1 var info = WeChatWASM.WX.GetSystemInfoSync(); 2 if (info == null) return false; 3 float py = (float)info.safeArea.top / (float)info.windowHeight; 4 float by = ((float)info.windowHeight - (float)info.safeArea.bottom) / (float)info.windowHeight; 5 6 m_SafeAreaContainer.offsetMax = new Vector2(m_SafeAreaContainer.offsetMax.x, m_SafeAreaContainer.offsetMax.y - cs.referenceResolution.y * py); 7 m_SafeAreaContainer.offsetMin = new Vector2(m_SafeAreaContainer.offsetMin.x, m_SafeAreaContainer.offsetMin.y + cs.referenceResolution.y * by); 8 9 cs.referenceResolution = new Vector2(cs.referenceResolution.x, cs.referenceResolution.y * (1 - (py + by)));
使用微信自带的获取接口
safeArea | Object | 在竖屏正方向下的安全区域。部分机型没有安全区域概念,也不会返回 safeArea 字段,开发者需自行兼容。 | |||||||||||||||||||||||||||||
|
但是上面的只能适配刘海屏和摄像头,微信还有菜单按钮(返回和更多),可能会遮挡游戏界面
微信倒是提供了获取胶囊体信息的接口
Object wx.getMenuButtonBoundingClientRect()
基础库 2.1.0 开始支持,低版本需做兼容处理。
微信 Windows 版:支持
微信 Mac 版:支持
功能描述
获取菜单按钮(右上角胶囊按钮)的布局位置信息。坐标信息以屏幕左上角为原点。
返回值
Object
菜单按钮的布局位置信息
属性 | 类型 | 说明 |
---|---|---|
width | number | 宽度,单位:px |
height | number | 高度,单位:px |
top | number | 上边界坐标,单位:px |
right | number | 右边界坐标,单位:px |
bottom | number | 下边界坐标,单位:px |
left | number | 左边界坐标,单位:px |
按理说只需要把上面通过微信获取的safe的top值更换成胶囊体的bottom,就可以完成适配,但还有referenceResolution这个影响,导致它会有误差(可能是方案不对)
所以先研究一下referenceResolution
Scale With Screen Size
使用 Scale With Screen Size 模式时,可以根据指定参考分辨率的像素来指定位置和大小。如果当前屏幕分辨率大于参考分辨率,则画布会保持只具有参考分辨率的分辨率,但是会放大以便适应屏幕。如果当前屏幕分辨率小于参考分辨率,则画布会相应缩小以适应屏幕。
如果当前屏幕分辨率的宽高比与参考分辨率不同,则单独缩放每个轴以适应屏幕会形成非一致缩放,通常不希望发生这种情况。相反,ReferenceResolution 组件会使画布分辨率偏离参考分辨率,以便遵循屏幕的宽高比。可以使用 Screen Match Mode 设置控制此偏离的行为方式。
================================================================
em...上面的方案可能也没问题,但是还是看看官方的方案:
var info = WX.GetWindowInfo(); float py = (float)info.safeArea.top / (float)info.windowHeight; // Rootrect初始时设置其Anchor,使其与父节点一样大,也就是屏幕的大小 // 调整屏幕移到刘海屏下面, Rootrect.anchorMin = new Vector2((float)info.safeArea.left / (float)info.windowWidth, -(float)info.safeArea.top / (float)info.windowHeight); // 重新计算缩放,让高度占满刘海屏以下的区域 cs.referenceResolution = new Vector2(cs.referenceResolution.x, cs.referenceResolution.y * (1.0f+py));
他这个方案总体好像是没问题,但实践一下就发现有问题(可能没按照正确的锚点绑定关系设定,但你也没说啊)
下面做了一下修改
anchorMax:修改右边锚点和上边锚点
但一般左右不用做适配,这里先忽略
上边锚点,在全屏自适应下是1,对应适配上面安全区(safeArea.top):1-(float)info.safeArea.top / (float)info.windowHeight
anchorMin:修改左边锚点和下边锚点
上边锚点,在全屏自适应下是0,对应适配下面安全区(safeArea.bottom):1-(float)info.safeArea.bottom / (float)info.windowHeight
// 重新计算缩放,让高度占满刘海屏以下的区域 cs.referenceResolution = new Vector2(cs.referenceResolution.x, cs.referenceResolution.y * (1.0f + py + (1 - by)));
这里加上底部做的适配
完美适配!如果觉得上面空白或者黑着不好看的,可以加一个顶部或底部背景图,设置好锚点
(忘记了,胶囊体的适配是把上面安全区的top调用更改为 胶囊体信息的bottom即可)