效果展示:
如果感觉文章有用的,也烦请大家多多支持(扫描上面二维码n(*≧▽≦*)n)!!❤❤❤
unity开发微信好友排行榜可以说是把我虐的体无完肤,但为了拿下这功能,硬壳了三天,把我所踩过的坑分享给大家,以下为好友排行实现,群排行实现方式类似
无废话,干活分享,对照一步步做即可实现,不明白的小伙伴欢迎留言~~~
1、勾选好友关系链
打包时要勾选使用好友关系链,这样打包的时候才会把开放数据域(以下做介绍)打到工程中
2、添加开放数据域渲染库
unity开发微信小游戏需要添加开放数据域渲染库,否则打包完上传MP平台的时候会报错
添加地址:http://mp.weixin.qq.com/wxopen/plugindevdoc?appid=wx7a727ff7d940bb3f&token=&lang=zh_CN
3、实现方式
看一下官方建议
所以大概流程就是使用 wx.setUserCloudStorage()将当前用户的游戏数据托管在微信后台,然后再使用wx.getFriendCloudStorage()获取一个对象列表,即为好友列表,包含好友信息和成绩,但wx.getFriendCloudStorage()在For unity的sdk中是不存在的,因为只能在开放数据域中使用
4、主域和开放数据域
主域:主进程作用域
开放数据域:是一个封闭、独立的 JavaScript 作用域。开放数据域是微信端特有的功能,使用它可以让开发者创建一个“子域”,并且只有在这个“子域”中,才能拿到用户相关的数据。
也就是说,在主域中写主要的逻辑,在开放数据域中获取好友信息然后渲染列表,那么主域和开放数据域之间是怎样通信的呢
5、主域和开放数据域之间的通信
主域 -> 开放数据域
主域使用WX.GetOpenDataContext().PostMessage(msg);向开放数据域中发送消息,开放数据域通过wx.onMessage监听来自主域的消息
开放数据域 -> 主域
主域只能通过sharedCanvas与开放数据域“通信”,开放数据域将数据渲染在sharedCanvas上,然后主域将sharedCanvas渲染到屏幕上
★就是说开放数据域中写样式和获取数据,渲染在sharedCanvas中,然后unity端将sharedCanvas渲染在canvas上,以此来完成微信好友排行的功能
6、unity需要做的工作
了解完环境配置,实现逻辑和定义以后,下面开始着手实现好友排行,微信伙伴为我们封装好了大部分功能,所以实现起来还是很简单的,就是过程可能会碰到很多坑
1)新建一个canvas,渲染模式一定要是Overlay,或者其他模式但不能使用相机渲染,否则会有不能滑动的后果(土亢)
2)新建一个空对象,添加RawImage
3)拖入一张图片,TextureType设置为Sprite(2D and UI),拖入到RawImage中
4)在需要显示好友排行的时候,使用WX.ShowOpenData()设置显示的区域
// 注意这里传x,y,width,height是为了点击区域能正确点击,x,y 是距离屏幕左上角的距离,宽度传 (int)RankBody.rectTransform.rect.width是在canvas的UI Scale Mode为 Constant Pixel Size的情况下设置的。
/**
* 如果父元素占满整个窗口的话,pivot 设置为(0,0),rotation设置为180,则左上角就是离屏幕的距离
* 注意这里传x,y,width,height是为了点击区域能正确点击,因为开放数据域并不是使用 Unity 进行渲染而是可以选择任意第三方渲染引擎
* 所以开放数据域名要正确处理好事件处理,就需要明确告诉开放数据域,排行榜所在的纹理绘制在屏幕中的物理坐标系
* 比如 iPhone Xs Max 的物理尺寸是 414 * 896,如果排行榜被绘制在屏幕中央且物理尺寸为 200 * 200,那么这里的 x,y,width,height应当是 107,348,200,200
* x,y 是距离屏幕左上角的距离,宽度传 (int)RankBody.rectTransform.rect.width是在canvas的UI Scale Mode为 Constant Pixel Size的情况下设置的
* 如果是Scale With Screen Size,且设置为以宽度作为缩放,则要这要做一下换算,比如canavs宽度为960,rawImage设置为200 则需要根据 referenceResolution 做一些换算
* 不过不管是什么屏幕适配模式,这里的目的就是为了算出 RawImage 在屏幕中绝对的位置和尺寸
*/
//scaler为渲染本身canvas的CanvasScaler
var referenceResolution = scaler.referenceResolution;
//RankBody为新建的RawImage
var p = RankBody.transform.position;
WX.ShowOpenData(RankBody.texture, (int)p.x, Screen.height - (int)p.y, (int)((Screen.width / referenceResolution.x) * RankBody.rectTransform.rect.width), (int)((Screen.width / referenceResolution.x) * RankBody.rectTransform.rect.height));
5)使用WX.GetOpenDataContext().PostMessage(msg)向开放数据域发送渲染通知,因为开放数据域已经封装好了基本的渲染功能,所以直接按照先放提供的代码即可
//传入到开放数据域的数据格式,可自定义增加需要的字段
//public class OpenDataMessage
//{
// public string type;
// public string shareTicket;
// public int score;
//}
//可查看WX-WASM-SDK-V2/Runtime/wechat-default/open-data/index.js中有对type字段值的枚举
openDataMessage.type = "showFriendsRank";
string msg = JsonMapper.ToJson(openDataMessage);
WX.GetOpenDataContext().PostMessage(msg);
6)需要关闭好友排行的时候,使用WX.HideOpenData()关闭区域
WX.HideOpenData();
7)向微信后台保存用户信息(可以发生在前端,可以发生在后端)
OpenDataMessage msgData = new OpenDataMessage();
msgData.type = "setUserRecord";
msgData.score = "成绩";
string msg = JsonUtility.ToJson(msgData);
WX.GetOpenDataContext().PostMessage(msg);
后端用法
https://developers.weixin.qq.com/minigame/dev/api-backend/open-api/data/storage.setUserStorage.html
7、开放数据域中需要做的工作
先了解每个文件夹的作用
WX-WASM-SDK-V2/Runtime/wechat-default/open-data下为开放数据域的文件
~/data存放数据逻辑和工具类
~/render/image 存放开放数据域需要的图片,因为开放数据域不支持外部图片url,所以要不将图片放到image文件夹中,要不在主域中将图片下载好,然后传进开放数据域中
~/render/styles 存放开放数据域的wxss样式
~/render/tpls 存放开放数据域的wxml模版
1)注释测试语句,这是示例应该怎样存用户数据
2)编辑模版样式 由于小游戏没有new Function 或者 eval 的能力,所以模版的编译只能在外部完成,然后将模版的内容复制到WX-WASM-SDK-V2/Runtime/wechat-default/open-data/tpls/friendRank.js文件中,这里可以寻找前端朋友帮助
TIPS:图片一定要用双标签,text标签的值一定要放在value中,不要放在标签内,不要问为什么(土亢)因为这是一记响亮的耳光
3)样式编辑,将写好的wxss复制到WX-WASM-SDK-V2/Runtime/wechat-default/open-data/styles/friendRank.js中
TIPS:宽高需要手动计算,排版方式默认为从左到右,一些复合的wxss无法使用,这也不要问为什么,因为这是另外一记响亮耳光(土亢)
友善建议:直接下载官方demo,https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/tree/main/Demo/Ranking,然后改,因为我之前做过小程序,所以非常自信的写了一个模版样式,于是就出现了上面的两记耳光,抽了我整整一天,最终用了官方示例改的::>_<::
8、以弹窗的形式展示好友列表
以上工作做完之后,不出意外情况,好友列表可以正常渲染了,但这里又碰见了另外一个问题,开放数据域的渲染由于跟unity的渲染有一些冲突,所以会干扰主域UI的渲染,效果如下
这基本是没法玩的,这又壳了将近一天的时间发现,如果好友排名以弹窗的形式展示,关闭弹窗的时候使用WX.HideOpenData()关闭开放数据域即可解决这个问题
并在后期也得到了官方对该问题的验证
最终效果呈现
可以微信添加minigamedevop08小游戏研发助手8号咨询自己需要解决的问题,上面的验证就是他帮助我找技术人员回复的,非常感谢
非常欢迎大家扫码体验,并提出宝贵建议,也非常感谢能读到这里,希望此文章对您有所帮助
为啥不提供把排行榜数据返回过来我自己通过unity渲染呢
用了弹窗显示排行榜还是会出现Unity渲染问题
这可怎么办啊,我也是
而且小程序的官方DEMO也是没法运行,点击按钮什么都不显示
请问下显示 请进入设置页允许获取微信朋友信息 怎么回事,如何添加让玩家同意收集信息的按钮
排行榜里面的字体描边儿和阴影怎么设置?代码设置完并不生效