当前位置:   article > 正文

Unity开发微信小游戏-好友排行榜功能_unity微信小游戏好友排行榜

unity微信小游戏好友排行榜

前言

为了实现小游戏的好友排行榜功能,在无数坑里爬起来后,决定分享一下
以下所用的素材均来自官方DemoRanking开放数据域文档

实现效果

  • 点击排行榜图标,出现排行榜窗口
  • 加载展示好友排行榜
  • 滑动排行榜可滚动榜单
  • 点击底下按钮可分享到群聊
  • 点击排行榜外将隐藏排行榜
    效果

实现步骤

通往罗马的路不止一条,以下只是一种实现方式,仅供参考

设置

主要有两处设置

  • 微信公众平台配置排行榜细则
    • 功能 》游戏运营工具箱 》排行榜设置,如下(这是已经设置好的),点添加即可
      后台排行榜设置
    • 填写排行榜配置项,提交等待审核即可
      排行榜具体设置项
  • Unity内设置
    • 点击上方菜单栏微信小游戏,打开转换小游戏窗口,在下方设置列表里,将SDK功能选项底下的使用好友关系链勾选
      SDK设置

Unity场景配置

  • 该功能具体使用到的场景实体如下左图红框标示的,具体场景的展示如下右图
  • Canvas: 项目其它UI所在Canvas,与该功能无关,无需理会

    • RankBtn: 点击呼出排行榜的按钮,如无其它Canvas,想放在底下RankCanvas也是可以的,按钮点击事件绑定脚本(底下给出)里的ShowRank()
      按钮绑定
  • RankCanvas: 新建Canvas,用于展示排行榜相关内容的Canvas,渲染模式不能选摄像机,这里用的是覆盖OverlayCanvas Scaler设置如下,根据自己的需要来即可
    canvas配置

    PS:这是一个坑位,渲染模式选摄像机后,榜单将不能滚动

    • RankMask: 作为全屏幕的透明遮罩,大小与上层Canvas设置一致,为了实现点击可退出排行榜的功能,本质是一个不指定源图像的Image,并且添加Button属性,按钮绑定脚本里的HideRank()。未点击排行榜时不渲染,因此需SetActive(false),即名称旁边的勾取消掉 Active
    • RankBox: 里面包含了排行榜真正展示的内容,本身是什么不重要,只是为了更好地约束底下成员,这里是用一个不知道精灵属性的Sprite。同样的,一开始需SetActive(false)
      • Bg: 排行榜的背景图
      • FTitle: 排行榜标题
      • RankBody: 一个RawImage对象,由于实际渲染是上下颠倒的,所以旋转属性的x需设置为180,该对象即为小游戏概念里SharedCanvas渲染的占位纹理
      • SharedBtn: 一个按钮,点击可分享到群聊,绑定脚本里的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);
            }
        });
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 设置open-datakey
    • WX-WASM-SDK-V2/Runtime/wechat-default/open-data/index.js内,更改const RANK_KEY的值,改为前面在微信公众平台排行榜设置里配置的排行榜唯一标识
    • 在该文件内默认存在以下测试代码,会在第一次加载时给用户随机设置个分数,不需要去掉即可
      // test
      setUserRecord(RANK_KEY, Math.ceil(Math.random() * 1000));
      
      • 1
      • 2

更改榜单样式

如需更改榜单样式,可在WX-WASM-SDK-V2/Runtime/wechat-default/open-data/render进行更改,其中tpls为模板,styles为模板样式,模板标签跟小程序类似,可使用纯js语法结合模板字符串语法书写;样式就是普通的CSS

PS:如果模板使用了text标签,内容要写在标签属性value里,写在标签内可能不展示,算是一个小坑位

默认open-data里使用的是渲染引擎Layout,具体细致可看文档引擎插件Layout文档

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/669250
推荐阅读
相关标签
  

闽ICP备14008679号