房间
房间是 联机大厅 的基础能力。实时消息、状态与 RPC、Mirror 传输层都依赖房间流程。
房间能力覆盖进入房间、准备、开始、结束、重赛、离开、运行中换地图,以及玩家加入 / 离开等事件。房间流程通常需要由 IGP 桌面客户端按联调或正式流程启动游戏。
| 引擎 | 状态 | 说明 |
|---|---|---|
| Unity | Preview | 已提供完整房间主流程。 |
| GameMaker | 暂不支持 | 当前 GameMaker 首期不包含房间能力。 |
| Godot | 开发中 | 预览 runtime 已有房间生命周期调用。 |
- 已完成 启动与连接。
- 游戏通过 IGP 桌面客户端启动,并获取联机启动信息。
- Unity 场景中保留唯一的
IGPRuntimeManager和IGPMultiplayerRuntime。 - Godot 项目已注册
IGPGodotAutoload。
using UnityEngine;using IGP.Multiplayer;
public sealed class IGPRoomDriver : MonoBehaviour{ [SerializeField] private IGPMultiplayerRuntime runtimeManager;
private void OnEnable() { runtimeManager.RoomChanged += OnRoomChanged; runtimeManager.ConnectionChanged += OnRealtimeConnectionChanged; }
private void OnDisable() { runtimeManager.RoomChanged -= OnRoomChanged; runtimeManager.ConnectionChanged -= OnRealtimeConnectionChanged; }
private void OnRoomChanged(IGPRoomChangedEvent change) { Debug.Log($"Room {change.Kind}, flags={change.Changes}, id={change.Room?.id}");
if ((change.Changes & IGPRoomChangeFlags.Map) != 0) { Debug.Log($"Map changed to {change.Room?.mapPublicId}"); } }
private async void OnRealtimeConnectionChanged(IGPMultiplayerConnectionChangedEvent change) { if (change.IsReady && runtimeManager.CurrentRoomData.hostId == runtimeManager.PlayerId) { await runtimeManager.SetSceneGateAsync("arena-ready"); } }
public async void StartGame() { await runtimeManager.StartHostedGameAsync(); }
public async void FinishGame() { await runtimeManager.FinishHostedGameAsync(); }
public async void LeaveRoom() { await runtimeManager.LeaveHostedRoomAsync(); }
}SceneGate 是 RoomNode 当前运行时房间中的 KCP 状态,不属于 hosted 房间快照。所有客户端可通过 CurrentSceneGate 读取,并监听带 SceneGate flag 的 RoomChanged;房主在 realtime 连接建立后调用 SetSceneGateAsync。晚加入或重连的客户端应在 realtime Ready 后调用 GetSceneGateAsync,Owner 的定向响应会异步更新本地值。RoomNode 运行时房间销毁后该值自然消失。
GameMaker 当前暂不支持房间能力。
Godot 当前建议通过 autoload 调用房间能力。
using Godot;using IGP.GodotSDK.Autoload;
public partial class RoomPanel : Control{ private IGPGodotAutoload IGP => GetNode<IGPGodotAutoload>("/root/IGP");
public override void _Ready() { IGP.RoomSnapshotReceived += OnRoomSnapshotReceived; IGP.RoomEventReceived += OnRoomEventReceived; }
public async void Ready() { await IGP.SetReadyAsync(true); }
public async void StartGame() { await IGP.StartHostedGameAsync(); }
public async void FinishGame() { await IGP.FinishHostedGameAsync(); }
private void OnRoomSnapshotReceived(string connectionStatus) {} private void OnRoomEventReceived(int eventType, string roomId) {}}Godot 仍处于开发中,当前示例主要用于评估和对齐接入方式。
运行中换地图
Section titled “运行中换地图”如果一局结束后仍然保留同一个房间,IGP 桌面客户端或 lobby 选择新地图后,会通过新的房间快照通知游戏。
Unity 游戏侧监听 RoomChanged 的 Map flag:
runtimeManager.RoomChanged += change =>{ if ((change.Changes & IGPRoomChangeFlags.Map) != 0) { Debug.Log($"Map changed to {change.Room?.mapPublicId}"); }};事件参数中与地图相关的字段:
| 字段 | 说明 |
|---|---|
PreviousRoom | 变更前房间快照,可读取旧地图字段 |
Room | 已更新后的完整房间快照,可读取新地图字段 |
Changes | 包含 IGPRoomChangeFlags.Map |
同一个房间内地图字段变化时,RoomChanged 的 Changes 包含 Map。如果是离开旧房间再进入新房间,会依次收到 Left 和 Joined。
| 引擎 | 检查点 |
|---|---|
| Unity | realtime 连接建立后,房主调用 SetSceneGateAsync("arena-ready"),所有客户端通过 KCP 广播读到新值;运行中换地图时收到带 Map flag 的 RoomChanged。 |
| GameMaker | 当前不做房间验收。 |
| Godot | 收到 RoomSnapshotReceived,调用 SetReadyAsync(true) 成功。 |
常见问题 / 排查
Section titled “常见问题 / 排查”- 无法进入房间:先确认游戏是否由 IGP 桌面客户端启动。
- Unity 切场景后房间断开:检查是否创建了第二个
IGPRuntimeManager。 - Unity 没收到换地图事件:确认仍在同一个
roomId,且新房间快照里的mapPublicId或mapVersionId已变化。 - Unity SceneGate 未更新:确认调用方是当前房主,并且 realtime/KCP 已连接。
- Godot 收不到房间快照:确认已完成 bootstrap,并建立了房间联机连接。