# Unity Event Reference

这页把 Unity 当前对外可接的事件集中列出来。

先说推荐入口：

- 常规接入优先看 `IGPRuntimeManager`
- 如果你想要更适合挂 Unity Inspector、并且参数更完整的事件，再看 `IGPEventManager`

跨引擎统一语义见：

- `../../../../../core/contracts/runtime-events.md`
- `../../../../../docs/architecture/runtime-events-engine-mapping.md`

## 1. `IGPRuntimeManager` 事件

这是 Unity 项目最直接的官方运行时入口。

### 已接入主链路的事件


| 事件                            | 参数                                       | 什么时候触发          | 常见用途              |
| ----------------------------- | ---------------------------------------- | --------------- | ----------------- |
| `onConnectionStateChanged`    | `bool connected`                         | 连接状态变化时         | 更新“已连接 / 已断开”UI   |
| `onMessageReceived`           | `string messageType, object content`     | 收到 realtime 消息时 | 处理自定义消息           |
| `onError`                     | `string error`                           | 主链路报错时          | 统一报错和日志上报         |
| `onAuthorizationStateChanged` | `IGPAuthorizationState state`            | 授权状态变化时         | 控制启动门禁、遮罩、提示      |
| `onAuthorizationFailed`       | `string message`                         | 授权失败时           | 自定义失败提示或拦截逻辑      |
| `onRoomJoined`                | `Room room`                              | 成功进入房间时         | 初始化房间 UI、自动 ready |
| `onRoomUpdated`               | `Room room`                              | 房间快照更新时         | 刷新队伍、玩家、状态        |
| `onRoomLeft`                  | `Room room`                              | 离开房间时           | 清理房间内 UI 和本地状态    |
| `onMapChanged`                | `IGPMapChangeData mapChange`            | 同一房间的地图字段变化时    | 运行中切换 Unity 地图/场景 |
| `onHeartbeatSent`             | 无                                        | SDK 发心跳时        | 调试和链路观察           |
| `onTeamChanged`               | `string messageType, object content`     | 队伍变化消息到达时       | 刷新当前玩家队伍          |
| `onTeamInitialized`           | `string messageType, object content`     | 队伍初始化消息到达时      | 初始化队伍 UI          |
| `onTeamStatusUpdated`         | `string messageType, object content`     | 队伍状态更新时         | 刷新准备状态、队伍状态       |
| `onHostTransferred`           | `string fromPlayerId, string toPlayerId` | 房主转移时           | 更新房主标记和主机权限       |


### 当前没有单独事件、需要直接看调用结果的能力

- 成就没有单独的 Unity 运行时事件
- `UnlockAchievementAsync(...)` 和 `ReportAchievementProgressAsync(...)` 需要直接使用返回结果

这对应 core contract 里的：

- `AchievementResult`

## 2. `IGPEventManager` 事件

这是 Unity 里的可选事件聚合器。

适合两种场景：

- 想在 Inspector 里直接挂事件
- 想拿到更适合业务层消费的整理后参数

### 当前已接入主链路的事件


| 事件                         | 参数                   | 什么时候触发          | 常见用途       |
| -------------------------- | -------------------- | --------------- | ---------- |
| `onConnected`              | `bool connected`     | 连接成功时           | 切在线状态      |
| `onDisconnected`           | `bool connected`     | 连接断开时           | 切离线状态      |
| `onConnectionStateChanged` | `bool connected`     | 连接状态变化时         | 统一连接状态入口   |
| `onMessageReceived`        | `IGPMessageData`     | 收到 realtime 消息时 | 直接拿标准化消息对象 |
| `onRoomJoined`             | `Room`               | 成功进房时           | 初始化房间数据    |
| `onRoomLeft`               | `Room`               | 离房时             | 清理房间态      |
| `onRoomUpdated`            | `Room`               | 房间快照更新时         | 刷新房间 UI    |
| `onMapChanged`             | `IGPMapChangeData`   | 同一房间的地图字段变化时    | 运行中切换地图/场景 |
| `onGameStarted`            | 无                    | 收到游戏开始房间事件时     | 切游戏内状态     |
| `onGameEnded`              | 无                    | 收到游戏结束房间事件时     | 切结算状态      |
| `onPlayerJoined`           | `IGPPlayerData`      | 收到玩家加入房间事件时     | 新增玩家 UI    |
| `onPlayerLeft`             | `IGPPlayerData`      | 收到玩家离开房间事件时     | 移除玩家 UI    |
| `onHostTransferred`        | `IGPPlayerData`      | 收到房主转移事件时       | 更新房主玩家信息   |
| `onGlobalStateChanged`     | `IGPStateChangeData` | 全局状态变化时         | 刷新全局状态     |
| `onPlayerStateChanged`     | `IGPStateChangeData` | 玩家状态变化时         | 刷新玩家状态     |
| `onStateChanged`           | `IGPStateChangeData` | 任意状态变化时         | 做统一状态分发    |
| `onRPCCall`                | `IGPRPCData`         | 收到 RPC 调用消息时    | 处理 RPC 请求  |
| `onRPCResponse`            | `IGPRPCData`         | 收到 RPC 返回消息时    | 处理 RPC 响应  |
| `onError`                  | `IGPErrorData`       | 主链路报错时          | 统一错误提示     |
| `onHeartbeatSent`          | 无                    | SDK 发心跳时        | 调试链路       |
| `onHeartbeatReceived`      | 无                    | 收到 `ping` 消息时   | 观察消息活性     |


### 当前已暴露但还没接上主链路的事件

这些入口现在在组件上能看到，但按当前实现还没有自动从主链路里发出来：


| 事件                  | 当前状态    |
| ------------------- | ------- |
| `onRoomCreated`     | 当前未接主链路 |
| `onPlayerUpdated`   | 当前未接主链路 |
| `onConnectionError` | 当前未接主链路 |
| `onRoomError`       | 当前未接主链路 |
| `onReconnecting`    | 当前未接主链路 |
| `onReconnected`     | 当前未接主链路 |


如果后面对外要把这几个也作为正式承诺，建议先补主链路实现，再在对外文档里升级口径。

## 3. 运行中换地图：`onMapChanged`

当玩家已经在同一个房间里完成一局，desktop / lobby 选择了新地图但游戏进程不重启时，Unity 侧监听：

```csharp
runtimeManager.onMapChanged.AddListener(HandleMapChanged);

private void HandleMapChanged(IGPMapChangeData mapChange)
{
    Debug.Log($"Map changed: {mapChange.previousMapPublicId} -> {mapChange.currentMapPublicId}");
}
```

触发条件：

- 仍然是同一个 `roomId`
- 新的 `RoomSnapshot` 里 `room.mapPublicId` 或 `room.mapVersionId` 发生变化
- SDK 会先更新 `CurrentRoomData`，同时继续触发常规 `onRoomUpdated`
- `onMapChanged` 是 Unity 方便业务接入的快捷事件，不替代 `RoomSnapshot` 作为房间真相来源

`IGPMapChangeData` 字段：

| 字段 | 含义 |
| --- | --- |
| `roomId` | 当前房间 ID |
| `previousMapPublicId` | 变更前的地图 public id |
| `previousMapVersionId` | 变更前的地图版本 id，可能为空 |
| `currentMapPublicId` | 变更后的地图 public id |
| `currentMapVersionId` | 变更后的地图版本 id，可能为空 |
| `room` | 已更新后的完整房间快照 |

游戏侧常见处理：

- 用 `currentMapPublicId` / `currentMapVersionId` 映射自己的 Unity scene、addressable key 或地图资源 ID
- 在收到事件后做本地结算清理、卸载旧地图、加载新地图
- 如果游戏有自己的准备状态，加载完成后再按业务需要重新 ready

## 4. 对应 core event 的映射

| Core Event | Unity 当前入口 |
| --- | --- |
| `ConnectionStateChanged` | `IGPRuntimeManager.onConnectionStateChanged` / `IGPEventManager.onConnectionStateChanged` |
| `AuthorizationStateChanged` | `IGPRuntimeManager.onAuthorizationStateChanged` / `IGPRuntimeManager.onAuthorizationFailed` |
| `RoomSnapshotUpdated` | `IGPRuntimeManager.onRoomJoined` / `onRoomUpdated` / `onRoomLeft`；地图字段变化时额外触发 `onMapChanged` |
| `RoomEvent` | `IGPRuntimeManager.onHostTransferred` / `IGPEventManager.onPlayerJoined` / `onPlayerLeft` / `onGameStarted` / `onGameEnded` |
| `RealtimeMessageReceived` | `IGPRuntimeManager.onMessageReceived` / `IGPEventManager.onMessageReceived` |
| `Detached` | 当前 Unity 没有单独对外运行时事件，通常通过连接状态变化和错误感知 |
| `ErrorReported` | `IGPRuntimeManager.onError` / `IGPEventManager.onError` |
| `AchievementResult` | 当前 Unity 直接看成就调用返回值 |

## 5. 常见选择

- 只想最快接进业务：优先用 `IGPRuntimeManager`
- 想在 Unity Inspector 里绑事件，或者想拿整理后的消息对象：加 `IGPEventManager`
- 想做成就提示：Unity 里现在优先直接看成就调用结果，不要等单独事件

## 6. 参考样例

- `Samples~/StarterDemo`
- `Samples~/RoomLifecycle`
- `Samples~/RealtimeMessaging`
- `Samples~/HostedPlayground`
