【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 字段,开发者需自行兼容。
 
 结构属性类型说明
  left number 安全区域左上角横坐标
  right number 安全区域右下角横坐标
  top number 安全区域左上角纵坐标
  bottom number 安全区域右下角纵坐标
  width number 安全区域的宽度,单位逻辑像素
  height number 安全区域的高度,单位逻辑像素

 但是上面的只能适配刘海屏和摄像头,微信还有菜单按钮(返回和更多),可能会遮挡游戏界面

 微信倒是提供了获取胶囊体信息的接口

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即可)

posted @ 2024-10-31 15:14  lovewaits  阅读(73)  评论(0编辑  收藏  举报