# Mirror Transport Quickstart

这份文档只讲一件事：

- 怎么把 `IGPMirrorTransport` 挂到 Mirror 的 `Transport` 位置里

适用对象很明确：

- 你的 Unity 项目已经在用 Mirror
- 你现在要把 Mirror 的传输层接到 IGP

前提是你已经准备好：

- Unity `2022.3 LTS`
- Mirror
- `cn.indiegp.sdk.unity`
- `cn.indiegp.sdk.unity.mirror-transport`

Mirror 版本口径：

- 最低兼容 `v89.0.0`
- 推荐使用 `v90.0.0` 或更高版本
- 默认不需要额外宏定义；`IGP_MIRROR_HAS_SERVER_CONNECTED_WITH_ADDRESS` 只是备用开关，只有在你确认项目里的 Mirror 已经包含新版连接回调，并且明确要让本包直接调用它时才需要添加

如果你还没先跑通 IGP 主链路，先看：

- `../../IGP.UnitySDK/Documentation~/QUICKSTART.md`

## 1. 安装包

先保证工程里的 `Packages/manifest.json` 至少有这两行：

```json
"cn.indiegp.sdk.unity": "file:../../../../adapters/unity/Runtime/IGP.UnitySDK",
"cn.indiegp.sdk.unity.mirror-transport": "file:../../../../adapters/unity/Runtime/IGP.UnitySDK.MirrorTransport"
```

Mirror 仍然按你们项目自己的接法导入。

## 2. 场景里要放什么

最少要有两块：

1. 一块 IGP runtime
2. 一块 Mirror network

推荐最小结构：

- `IGPBootstrap`
  - `IGPRuntimeManager`
- `NetworkRoot`
  - `IGPMirrorTransport`
  - 你自己的 `NetworkManager`

重点只有两个：

- `IGPRuntimeManager` 要先存在
- `NetworkManager.transport` 要指向 `IGPMirrorTransport`

## 3. 最小接法

下面这份脚本就是最小可用接法：

```csharp
using IGP.UnitySDK;
using IGP.UnitySDK.MirrorTransport;
using Mirror;
using UnityEngine;

public sealed class MirrorIgpBootstrap : NetworkManager
{
    [SerializeField] private IGPRuntimeManager runtimeManager;
    [SerializeField] private IGPMirrorTransport transport;

    public override void Awake()
    {
        runtimeManager ??= FindObjectOfType<IGPRuntimeManager>();
        transport ??= FindObjectOfType<IGPMirrorTransport>();

        if (runtimeManager == null || transport == null)
        {
            Debug.LogError("[Mirror IGP] Missing IGPRuntimeManager or IGPMirrorTransport.");
            enabled = false;
            return;
        }

        this.transport = transport;
        networkAddress = "host";
        dontDestroyOnLoad = true;
        runInBackground = true;
        autoCreatePlayer = true;

        base.Awake();
    }
}
```

说明：

- `networkAddress = "host"` 时，client 会去连当前房主
- 如果你明确知道要连哪个玩家，也可以把 `networkAddress` 设成那个玩家的 id

## 4. 启动顺序

这块 transport 不是独立联网层，它依赖 IGP 已经把房间和数据面拉起来。

所以顺序要是：

1. 先让 `IGPRuntimeManager` 完成房间附着
2. 再让 IGP 数据面连上
3. 最后再启动 Mirror 的 host / client

简单说：

- 不要一进场景就直接 `StartHost()` / `StartClient()`
- 先等 IGP 这边已经进房、并且数据面可用

如果你们项目已经有自己的房间进入流程，最稳的做法就是在“房间已附着”之后再启动 Mirror。

## 5. host / client 怎么起

host 侧：

- 先让 IGP 完成进房
- 再调用 `StartHost()`

client 侧：

- 先让 IGP 完成进房
- 把 `networkAddress` 设成 `"host"`
- 再调用 `StartClient()`

## 6. 什么时候算接通了

至少确认这几件事：

1. IGP 已经进到同一个房间
2. IGP 数据面已经连上
3. Mirror host 已经启动
4. Mirror client 已经连上
5. 双边能互相收发 Mirror 消息

如果你想直接看一套完整可跑的例子，直接看：

- `samples/unity/MirrorTransportDemo/README.md`

这个 demo 也是按同样口径提供的：

- 它是给 Mirror 项目的专项接入示例
- 不是通用 Unity starter demo

## 7. 常见问题

### 一直连不上

优先检查：

- `IGPRuntimeManager` 是不是还没进房
- 数据面是不是还没连上
- client 侧是不是太早 `StartClient()`

### 切场景后断了

优先检查：

- `IGPRuntimeManager` 有没有被场景切换销毁
- `NetworkManager` 和 `IGPMirrorTransport` 有没有被重复创建

### 为什么不是普通 IP 和端口

因为这块不是直接走传统直连。

Mirror 看到的是一个 transport，但底下实际用的是 IGP 已经建立好的房间和数据面。
