赞
踩
为了实现小游戏的好友排行榜功能,在无数坑里爬起来后,决定分享一下
以下所用的素材均来自官方Demo
— Ranking、开放数据域文档
通往罗马的路不止一条,以下只是一种实现方式,仅供参考
主要有两处设置
微信小游戏
,打开转换小游戏窗口,在下方设置列表里,将SDK功能选项底下的使用好友关系链勾选Canvas: 项目其它UI所在Canvas,与该功能无关,无需理会
ShowRank()
RankCanvas: 新建Canvas,用于展示排行榜相关内容的Canvas,渲染模式不能选摄像机
,这里用的是覆盖Overlay
,Canvas Scaler
设置如下,根据自己的需要来即可
PS:这是一个坑位,渲染模式选摄像机后,榜单将不能滚动
Canvas
设置一致,为了实现点击可退出排行榜的功能,本质是一个不指定源图像的Image
,并且添加Button
属性,按钮绑定脚本里的HideRank()
。未点击排行榜时不渲染,因此需SetActive(false)
,即名称旁边的勾取消掉 Sprite
。同样的,一开始需SetActive(false)
RawImage
对象,由于实际渲染是上下颠倒的,所以旋转属性的x
需设置为180
,该对象即为小游戏概念里SharedCanvas
渲染的占位纹理ShareGroupRank()
Ranking: 一个空对象,用于绑定脚本,其中,脚本的一些配置如下
PS:个人习惯,你也可以把脚本绑定在其它对象上,自己喜欢就好
官方Demo
一致,可根据自己需要更改using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using WeChatWASM; /// <summary> /// 排行榜相关测试 /// </summary> /// 目前只有好友排行榜功能 /// 后续可整合加入其它排行榜 public class RankingTest : MonoBehaviour { /// <description> /// <list type="table"> /// 微信小游戏 主域 与 开放数据域 的理解 /// <item> /// 主域 /// <description>即我们进入游戏玩的、看到的内容(canvas),除开放数据域之外的,本质就是我们的游戏项目</description> /// </item> /// <item> /// 开放数据域 /// <description> /// 一个私有的域,或者说canvas(sharedCanvas),本质是一个子文件夹(由game.json配置的) /// 里面可以调用一些敏感数据API,然后渲染在sharedCanvas /// 主域能做的就是把内容设置好的sharedCanvas渲染在界面的某处 /// </description> /// </item> /// </list> /// </description> // 排行榜内容的实际显示,即小游戏开放数据域的sharedCanvas public RawImage RankBody; // 当展开排行榜时全屏的一个遮罩 // 用于监听防止点击其它区域,同时监听关闭(实现点击排行榜外时关闭排行榜) public GameObject RankMask; // 排行榜内容的集合 // 层级关系 // RankBox // - Bg // - RankBody // - SharedBtn(可加) // - 其它排行呼出按钮(可加) // 当排行榜显示/隐藏,只需控制RankBox的显隐 public GameObject RankBox; // private bool isShow = false; // Start is called before the first frame update void Start() { Init(); GroupSharedInit(); } /// <summary> /// 通知开放数据域渲染排行榜 /// </summary> private void ShowOpenData() { // 显示排行榜相关的Unity-UI RankMask.SetActive(true); RankBox.SetActive(true); // 注意这里传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 在屏幕中绝对的位置和尺寸 */ // CanvasScaler scaler = gameObject.GetComponent<CanvasScaler>(); // var referenceResolution = scaler.referenceResolution; // 获取canvas的单位像素,即上面RankCanvas设置的大小 var referenceResolution = new Vector2(1080, 1920); 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)); } /// <summary> /// 显示好友排行榜 /// </summary> public void ShowRank() { Debug.Log("展示排行榜"); // 渲染数据 this.ShowOpenData(); // 通知开放数据域 string msg = JsonUtility.ToJson(OpenDataMessage.SHOW_FRIENDS_RANK()); WX.GetOpenDataContext().PostMessage(msg); } /// <summary> /// 隐藏排行榜 /// </summary> public void HideRank() { // 隐藏排行榜相关实体 RankMask.SetActive(false); RankBox.SetActive(false); Debug.Log("隐藏排行榜"); // 调用WX-API通知开放数据域执行隐藏操作,防止一些材质混乱问题 WX.HideOpenData(); } public void ShareGroupRank() { // 分享信息到群聊 WX.ShareAppMessage(new ShareAppMessageOption() { // 标题 title = "最强战力排行榜!谁是第一?", // 分享的路径参数,与OnShow约定进行判断 query = "action=show_group_rank", // 封面 - 后续可更换为自己的,但需要在微信公众平台配置 // https://developers.weixin.qq.com/minigame/dev/guide/open-ability/share/share.html imageUrl = "https://mmgame.qpic.cn/image/5f9144af9f0e32d50fb878e5256d669fa1ae6fdec77550849bfee137be995d18/0", }); } /// <summary> /// 初始化 /// </summary> /// <description>可用于做一些需要的初始化、判断什么的,这里暂时没有</description> void Init() { Debug.Log("初始化排行榜"); } /// <summary> /// 初始化群排行榜分享 /// </summary> void GroupSharedInit() { /** * 使用群排行功能需要特殊设置分享功能,详情可见链接 * https://developers.weixin.qq.com/minigame/dev/guide/open-ability/share/share.html */ WX.UpdateShareMenu(new UpdateShareMenuOption() { withShareTicket = true, isPrivateMessage = true, }); /** * 群排行榜功能需要配合 WX.OnShow 来使用,整体流程为: * 1. WX.UpdateShareMenu 分享功能; * 2. 监听 WX.OnShow 回调,如果存在 shareTicket 且 query 里面带有启动特定 query 参数则为需要展示群排行的场景 * 3. 调用 WX.ShowOpenData 和 WX.GetOpenDataContext().PostMessage 告知开放数据域侧需要展示群排行信息 * 4. 开放数据域调用 wx.getGroupCloudStorage 接口拉取获取群同玩成员的游戏数据 * 5. 将群同玩成员数据绘制到 sharedCanvas */ WX.OnShow((OnShowListenerResult res) => { string shareTicket = res.shareTicket; Dictionary<string, string> query = res.query; if (!string.IsNullOrEmpty(shareTicket) && query != null && query["action"] == "show_group_rank") { OpenDataMessage msgData = OpenDataMessage.SHOW_GROUP_FRIENDS_RANK(shareTicket); string msg = JsonUtility.ToJson(msgData); // 展示排行榜 this.ShowOpenData(); // 通知开放数据域 WX.GetOpenDataContext().PostMessage(msg); } }); } }
OpenDataMessage
,与开放数据域通信的消息结构using UnityEngine.SocialPlatforms.Impl; [System.Serializable] public class OpenDataMessage { // type 用于表明消息类型 // 需与open-data里约定一致 public string type; public string shareTicket; public int score; /* 底下的静态方法只是为了使用方便 */ /// <summary> /// 展示好友排行榜 /// </summary> /// <returns></returns> public static OpenDataMessage SHOW_FRIENDS_RANK() { OpenDataMessage message = new OpenDataMessage(); message.type = "showFriendsRank"; return message; } /// <summary> /// 展示群组排行榜 /// </summary> /// <param name="shareTicket">群分享对应的标识</param> /// <returns></returns> public static OpenDataMessage SHOW_GROUP_FRIENDS_RANK(string shareTicket) { OpenDataMessage message = new OpenDataMessage(); message.type = "showGroupFriendsRank"; message.shareTicket = shareTicket; return message; } /// <summary> /// 设置用户记录 /// </summary> /// <param name="score">分数</param> /// <returns></returns> public static OpenDataMessage SET_USER_RECORD(int score) { OpenDataMessage message = new OpenDataMessage(); message.type = "setUserRecord"; message.score = score; return message; } }
open-data
的key
WX-WASM-SDK-V2/Runtime/wechat-default/open-data/index.js
内,更改const RANK_KEY
的值,改为前面在微信公众平台
排行榜设置里配置的排行榜唯一标识// test
setUserRecord(RANK_KEY, Math.ceil(Math.random() * 1000));
如需更改榜单样式,可在WX-WASM-SDK-V2/Runtime/wechat-default/open-data/render
进行更改,其中tpls
为模板,styles
为模板样式,模板标签跟小程序类似,可使用纯js
语法结合模板字符串语法书写;样式就是普通的CSS
PS:如果模板使用了
text
标签,内容要写在标签属性value
里,写在标签内可能不展示,算是一个小坑位
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。