# TapBattleClient.MatchRoom

# 功能描述

自动匹配房间,根据匹配参数查找合适的房间。如果找到符合条件的房间则加入,如果没有找到则自动创建新房间。这是最常用的匹配方式。

# 方法签名

public static void MatchRoom(MatchRoomOption option)

# 参数说明

# MatchRoomOption

参数名 类型 必填 说明
data MatchRoomConfig 匹配房间配置数据
success Action<MatchRoomSuccessResponse> 匹配成功回调
fail Action<TapCallbackResult> 匹配失败回调
complete Action<TapCallbackResult> 匹配完成回调

# MatchRoomConfig

字段名 类型 必填 说明
roomCfg RoomConfig 房间配置(不需要name字段
playerCfg PlayerConfig 玩家配置

# RoomConfig(用于匹配)

字段名 类型 必填 说明
maxPlayerCount int 房间最大人数
type string 房间类型
customProperties string 自定义房间属性(JSON字符串)
matchParams MatchParams 匹配参数(用于匹配算法)
name - - 注意:MatchRoom不需要name字段

# MatchRoomSuccessResponse

字段名 类型 说明
roomInfo RoomInfo 匹配到的房间信息
errMsg string 成功时为"matchRoom:ok"

# 使用说明

# 匹配逻辑

  1. 服务器根据匹配参数查找符合条件的房间
  2. 如果找到未满的房间,则加入该房间
  3. 如果没有找到,则自动创建新房间

# 匹配参数说明

匹配时需要3个参数完全相等才能匹配成功:

  1. RoomConfig.type - 房间类型(如"新手区"、"高级区")
  2. MatchParams.level - 等级参数
  3. MatchParams.score - 分数参数

重要: 匹配是精确匹配,不是范围匹配。只有当这3个参数完全相等时,才能匹配到同一个房间。

# 范围匹配的实现

如果需要范围匹配(如100-200分的玩家匹配到一起),需要客户端自行实现区间映射

实现方式:

  1. 客户端预设范围区间等级(如:低级0-100、中级101-200、高级201-300)
  2. 判断玩家属于哪个区间
  3. 使用区间名称作为匹配参数,而不是具体数值

示例:

  • 玩家A分数100分 → 判断属于"中级" → 匹配参数设为"中级"
  • 玩家B分数150分 → 判断属于"中级" → 匹配参数设为"中级"
  • 两位玩家可以匹配到一起(因为都是"中级")

# 注意事项

  • 不需要name字段 - 与CreateRoom不同,MatchRoom的roomCfg中不需要提供name
  • 精确匹配 - 3个匹配参数必须完全相等才能匹配成功
  • 可能是房主 - 如果自动创建了新房间,你就是房主
  • 可能不是房主 - 如果加入了现有房间,你不是房主
  • 需要判断身份 - 匹配成功后需要检查自己是否是房主

# 代码示例

# 示例1:快速匹配

using UnityEngine;

public class QuickMatch : MonoBehaviour
{
    private string myPlayerId;

    public void StartQuickMatch()
    {
        TapBattleClient.MatchRoom(new MatchRoomOption
        {
            data = new MatchRoomConfig
            {
                roomCfg = new RoomConfig
                {
                    maxPlayerCount = 2,
                    type = "新手区",
                    matchParams = new MatchParams
                    {
                        level = "5",
                        score = "1000"
                    }
                }
            },
            success = (result) => {
                var roomInfo = result.roomInfo;
                Debug.Log($"匹配成功!房间ID: {roomInfo.id}");

                // 判断我是否是房主
                bool isOwner = (roomInfo.ownerId == myPlayerId);
                if (isOwner) {
                    Debug.Log("我创建了新房间,我是房主");
                } else {
                    Debug.Log("我加入了现有房间,等待房主开始");
                }

                ShowRoomUI(roomInfo, isOwner);
            },
            fail = (result) => {
                Debug.LogError($"匹配失败: {result.errMsg}");
            }
        });
    }

    private void ShowRoomUI(RoomInfo roomInfo, bool isOwner) { }
}

# 示例2:范围匹配实现

using UnityEngine;

public class RangeMatchExample : MonoBehaviour
{
    private string myPlayerId;
    private int playerScore = 150; // 玩家当前分数

    public void StartRangeMatch()
    {
        // 根据分数判断属于哪个区间
        string scoreRange = GetScoreRange(playerScore);
        string levelRange = GetLevelRange(playerScore);

        Debug.Log($"玩家分数: {playerScore},匹配区间: {scoreRange}, {levelRange}");

        TapBattleClient.MatchRoom(new MatchRoomOption
        {
            data = new MatchRoomConfig
            {
                roomCfg = new RoomConfig
                {
                    maxPlayerCount = 2,
                    type = "排位赛",  // 房间类型
                    matchParams = new MatchParams
                    {
                        level = levelRange,  // 使用区间名称,而不是具体数值
                        score = scoreRange   // 使用区间名称,而不是具体数值
                    }
                }
            },
            success = (result) => {
                Debug.Log($"匹配成功!房间ID: {result.roomInfo.id}");
                Debug.Log($"房间内玩家可能分数在100-200之间");
                
                bool isOwner = (result.roomInfo.ownerId == myPlayerId);
                ShowRoomUI(result.roomInfo, isOwner);
            },
            fail = (result) => {
                Debug.LogError($"匹配失败: {result.errMsg}");
            }
        });
    }

    // 将分数映射到区间
    private string GetScoreRange(int score)
    {
        if (score <= 100) return "低级";
        if (score <= 200) return "中级";
        if (score <= 300) return "高级";
        return "超级";
    }

    // 将等级映射到区间
    private string GetLevelRange(int score)
    {
        if (score <= 50) return "青铜";
        if (score <= 150) return "白银";
        if (score <= 250) return "黄金";
        return "钻石";
    }

    private void ShowRoomUI(RoomInfo roomInfo, bool isOwner) { }
}

# 最佳实践

  1. 使用区间映射 - 对于范围匹配需求,客户端预设区间等级,将具体数值映射到区间名称
  2. 合理的匹配参数 - 3个参数(type、level、score)需要平衡,既要保证匹配成功率,又要保证公平性
  3. 判断房主身份 - 匹配成功后立即判断是否是房主,显示不同UI
  4. 检查房间人数 - 判断房间是否已满,决定是否显示开始按钮
  5. 友好的等待UI - 匹配中和等待对手时显示友好的加载动画

# 相关API