ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

使用Photon托管Gorebox物理沙盒联机房间完整指南

使用Photon托管Gorebox物理沙盒联机房间完整指南 之前在本地跑 Gorebox 物理沙盒玩法时我和朋友的联机体验一直不太稳定同一个 WiFi 下面没有任何问题但只要朋友在家用宽带或者手机切成流量热点房间列表里就刷不出来加入房间往往长时间卡在连接界面。后来把问题定位到联机通道上才意识到这不是游戏逻辑本身的问题而是缺少一个稳定的网络中继层。Photon 就是用来解决这类实时联机问题的常用方案。本文以“用 Photon 托管 Gorebox 服务器”为主线从概念、账号准备、Unity 工程接入、房间创建与玩家同步到常见报错和运营建议完整梳理一套可照做的流程。如果你是玩家只是想稳定组成好友房间可以看到网络配置层面的关键点如果你是开发者想在自己做的物理沙盒玩法中加入类似 Gorebox 的多人联机本文的 PUN 2 接入思路同样适用。1. 背景与核心概念1.1 Gorebox偏重物理交互的多人沙盒Gorebox部分版本写作 GoreBox是一款使用 Unity 引擎开发的物理沙盒游戏。它的玩法核心在于自由摆放角色、载具、爆炸物和各类道具让玩家在一个高物理模拟的环境里设计自己的“演出”场景。这类游戏的特点决定了它非常适合多人联机物理效果会带来非常多不可预测的实时变化玩家之间的互动也正是乐趣所在。不过物理沙盒游戏对网络同步的要求比其他类型的游戏更高。角色碰撞、物体抛掷、爆炸冲击波等内容都会产生高频状态变化因此联机引擎不能只是简单转发聊天消息还需要考虑同步频率、数据压缩和不同物体之间的优先级。理解这一点是后面正确配置 Photon 房间属性的基础。1.2 Photon一套面向实时应用的多人在线框架Photon 是由 Exit Games 推出的实时多人网络框架在 Unity 生态中尤其常见。我们通常接触到的 PUNPhoton Unity Networking是它的 Unity 客户端插件此外还有 Fusion、Quantum、Photon Server 等不同形态的产品。它的核心工作方式是客户端先连接 Photon 云端节点再通过云节点创建房间、加入房间以及转发消息。借助 Photon 提供的中继能力普通项目不需要自己维护一台公网 IP 的物理服务器也可以让不同运营商、不同地区甚至不同国家的玩家走到同一个房间里。对于 Gorebox 这种需要快速联机的场景直接用 Photon Cloud 是最省事的托管方式同时也是官方方案里最常用的一条路。1.3 “托管服务器”到底托管了什么很多刚接触联机开发的朋友会把“托管服务器”等同于租一台 Linux 或者 Windows 云主机然后在上面跑服务端程序。但在 Photon Cloud 模式下“服务器”可以拆成两层来理解网络层由 Photon 云节点负责包括玩家连接认证、房间列表、消息转发、断线重连。玩法层由游戏客户端逻辑负责比如角色生成、物理计算、关卡切换、胜负判定。在使用 PUN 2 搭建的房间里房主其实承担了部分玩法层的逻辑而网络层仍然由 Photon 云来承担。你可以把这个过程理解为“把房间托管到了 Photon 上”而不是传统意义上的“把整个游戏状态跑在云服务器上”。这个概念先想清楚后面配置时就不会把两件事混在一起。从角色上可以这样划分角色需要关注的内容普通玩家游戏内置多人菜单、房间名、人数上限开发者/Mod 作者App ID、PUN 2 插件、PhotonView、RPC运营者Region 选择、CCU 用量、日志监控、版本更新如果你未来想完全摆脱玩家主机依赖则需要继续了解 Photon Server 私有部署或者 Fusion 的服务器托管模式这部分会在文章最后给出方向。1.4 为什么选择 Photon Cloud对于大多数 Gorebox 多人房间需求来说Photon Cloud 的优势集中在三点不需要公网 IP。玩家本机不管在路由器后面多深都能通过出站连接到 Photon 云节点。全球多区域节点。可以选择离玩家群体较近的固定区域降低延迟。免费额度即可起步。朋友之间联机普通的免费 CCU 套餐一般够用不必一上来就购买独立服务器。当然云托管不是万能的。Photon Cloud 做的是消息中继不是完整模拟全部物理世界所以高密度物理物体的同步仍然需要开发阶段做优化。这一点在暴力拆解的沙盒玩法里尤其明显后面最佳实践章节会专门展开。2. 环境准备与版本说明2.1 准备你的开发与运行环境无论你是想直接运营一个 Gorebox 房间还是想基于源码二次开发建议准备如下环境操作系统Windows 10/11 或 macOS如果是服务器则建议 Windows Server 2019/2022 开发工具Unity Hub Unity Editor本文以 Unity 2020.3 及以上为参考 联机插件Photon PUN 2 调试工具Unity Console 面板、Photon 官方 Dashboard 日志 游戏本体Gorebox 当前实际使用的客户端/开发工程需要特别说明Unity 版本和 PUN 2 的版本之间存在兼容关系。新版 Unity 从 2020 系列开始持续升级包管理器机制PUN 2 的导入方式也从前几年的 Asset Store 导入逐渐过渡到通过 Unity Package Manager 或者自定义离线包导入。因此本文给出的路径和菜单名称以常见情况为例实际操作时请以你安装的版本界面为准。此外如果未来的托管环境选择物理服务器或者自建虚拟机那么系统时间是否准确会直接影响 TLS 连接。很多人在部署 Photon 相关服务时遇到过证书验签失败排查到最后往往发现是 Windows 服务器没有同步 NTP 时间导致系统时间和真实时间偏差过大。建议在准备环境阶段就把时区、时间同步列入检查清单。2.2 注册 Photon 账号并创建应用使用 Photon Cloud 首先要拿到一个 App ID它相当于你的应用在 Photon 云端的“门牌号”。操作步骤如下打开 Photon 官网注册并登录 Dashboard。进入应用管理页面点击创建新应用。选择产品类型为 Photon PUN而不是 Fusion 或者 Bolt。填写应用名称创建成功后可看到一行 App ID。复制 App ID后续会填到 Unity 工程或 Gorebox 的联机配置里。需要注意App ID 每个应用唯一。如果你同时开发多个联机游戏需要创建多个应用分别管理而不能共用一个 App ID。否则两个项目之间会互相干扰甚至玩家的自定义属性和房间列表都会串掉。官网页面内容会不定期改版菜单名称可能不完全一致但“创建应用、拿到 App ID”这条主线不会变。2.3 理解免费额度与 CCUPhoton Cloud 的免费套餐通常以 CCUConcurrent Connected Users同时在线连接数来计量。一个 CCU 表示一个已经建立连接的在线的玩家。注意它既不是“月活跃用户”也不是“累计注册人数”而是某一时刻正在连接的数量。对于几个好友一起玩 Gorebox 的场景免费套餐足够起步。但是如果房间设置为长时间开放并且不断有新玩家进入同时在线人数一旦接近上限新连接可能会被拒。运营方向可以考虑限制单个房间的人数上限比如控制在 10 人以内。设置房间超时机制避免无人房间长时间占用连接。定期查看 Dashboard 的并发曲线评估是否需要升级套餐。CCU 不是唯一计费维度请求流量和应用版本也可能影响最终用量。正式运营前建议先在免费额度下观察一周再决定是否扩容。3. Photon 核心配置与概念拆解3.1 App ID、AppVersion、Region 三件套Photon 连接能不能成功最关键的三项配置就是 App ID、AppVersion 和 Region。它们的含义如下App ID标识你使用的是哪个 Photon 应用。AppVersion用于区分客户端版本。版本不同玩家之间无法互相发现和加入。比如 Gorebox 更新到新版本后旧版本客户端就不应该连接到新房间。Region选择靠近玩家的云节点区域。常见的节点包括美国东部、欧洲、亚洲等具体可用区域以 Dashboard 为准。在 Unity 中这三项配置通常保存在 PhotonServerSettings.asset 文件里。可以通过菜单进行编辑。如果项目支持脚本化配置也可以在运行时动态赋值。PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime 你的AppID; PhotonNetwork.PhotonServerSettings.AppSettings.FixedRegion cn;这里要提醒一点强行把 Region 写死为某一个区域可能让远处玩家延迟升高。更常见的做法是让 Photon 根据客户端网络自动选择最近节点也就是默认的 Region 策略。3.2 房间模型Photon 中的房间是玩家聚集的最小单位每个房间有自己的名称、人数上限、打开状态和可见状态。房间属性还可以扩展自定义字段例如保存当前地图名称、玩法模式、玩家队伍信息等。房间状态的设计直接影响玩家体验IsOpen房间是否还可以加入。比赛已经开始时通常设置为 false。IsVisible房间是否出现在公开列表里。好友专用房间可以设置为 false。MaxPlayers房间允许的最大玩家数。CustomRoomProperties自定义房间属性通常配合房间列表筛选使用。使用 PUN 2 创建房间的代码如下RoomOptions options new RoomOptions(); options.IsOpen true; options.IsVisible true; options.MaxPlayers 8; options.CustomRoomProperties new Hashtable { { mode, sandbox }, { scene, World01 } }; PhotonNetwork.CreateRoom(Gorebox_Room_01, options);这一段代码是后续实战部分的基础逻辑。房间属性中的 scene 字段可以用来自动加载对应关卡。3.3 PhotonView 与对象同步在多人在线游戏里并不是所有物体都需要同步。PhotonView 是 PUN 2 中控制同步的最小单元。只有挂载了 PhotonView 的物体Photon 才会对它进行数据观察和消息同步。一般在 Gorebox 类型的物理沙盒里需要同步的对象包括玩家角色位置、旋转、动画状态、生命值。场景中的关键交互物体可移动的道具、载具、爆炸物。玩法相关的逻辑对象开关、门、生成器。对于静态装饰物则不需要挂载 PhotonView否则只会白白增加网络负担。挂载 PhotonView 时还要检查它的 Owner 概念。Owner 是指当前对这个对象拥有控制权的客户端通常是生成该对象的客户端。在 RPC 调用中可以用PhotonView.Owner判断权限。3.4 RPC 与事件分发除了持续的属性同步很多玩法需要“让对方执行某段逻辑”此时 RPC 是最直接的方式。RPC 全称 Remote Procedure Call可以让远程客户端执行一个本地定义好的方法。使用 RPC 前需要给方法添加[PunRPC]特性然后通过 PhotonView 调用例如[PunRPC] public void PlayExplosion(Vector3 position, float radius) { // 在本地播放爆炸特效和伤害判定 } private void SendExplosionToAll(Vector3 pos, float radius) { photonView.RPC(PlayExplosion, RpcTarget.All, pos, radius); }这里的关键点是RPC 只传递参数和方法名不传递复杂对象引用。如果参数过多建议把数据打包成一个结构后序列化。在物理沙盒类玩法里爆炸、碰撞、击杀事件都非常适合用 RPC 广播而角色位置变化则交给 PhotonView 的自动同步。4. 实战使用 Photon 托管 Gorebox 多人房间4.1 导入 Photon PUN 2在 Unity 工程中导入 PUN 2 的方式取决于你的 Unity 版本。如果你使用的是较老版本可以打开 Asset Store 搜索 Photon PUN 2如果新版已经转向 Package Manager也可以下载官方的 PUN 2 unitypackage 后双击导入。导入完成后项目里会出现 Photon 菜单。打开菜单里的 PhotonServerSettings 配置文件把前面拿到的 App ID 填写到对应字段。App ID Realtime: 你的AppID Fixed Region: 可留空让Photon自动选择 Use Default Region: 勾选如果你的 Gorebox 工程是下载来的并且已经被作者配置过 App ID那么不建议随意更换。如果你希望让房间只能由自己的好友加入可以创建一个新的 Photon 应用然后把 App ID 换成新的这样就能把玩家隔离在自己的应用空间内。4.2 编写连接启动器下面创建一个名为 GoreboxLauncher 的脚本放在场景的空物体上。它负责完成连接、进大厅、创建或加入房间这一系列流程。// 文件路径Assets/Scripts/GoreboxLauncher.cs using Photon.Pun; using Photon.Realtime; using UnityEngine; public class GoreboxLauncher : MonoBehaviourPunCallbacks { [SerializeField] private byte maxPlayers 8; [SerializeField] private string roomName Gorebox_Sandbox; [SerializeField] private string gameVersion 1.0; private void Start() { PhotonNetwork.AutomaticallySyncScene true; PhotonNetwork.GameVersion gameVersion; PhotonNetwork.ConnectUsingSettings(); } public override void OnConnectedToMaster() { Debug.Log(已连接到 Photon Master Server); PhotonNetwork.JoinLobby(); } public override void OnJoinedLobby() { Debug.Log(已进入大厅开始创建房间); RoomOptions options new RoomOptions { IsOpen true, IsVisible true, MaxPlayers maxPlayers }; PhotonNetwork.CreateRoom(roomName, options); } public override void OnCreatedRoom() { Debug.Log(房间创建成功 roomName); } public override void OnJoinRoomFailed(short returnCode, string message) { Debug.LogWarning(加入房间失败 message); RoomOptions options new RoomOptions { IsOpen true, IsVisible true, MaxPlayers maxPlayers }; PhotonNetwork.CreateRoom(roomName, options); } }这个脚本的核心思路是先连接到 Photon Master Server再进入大厅最后创建指定名称的房间。加入失败时会自动尝试重新创建房间适合快速搭建好友房间。有一个细节需要注意PhotonNetwork.GameVersion必须与所有客户端一致。如果你和朋友的版本号分别是 1.0 和 1.1即使 App ID 相同也无法进入彼此的房间列表。4.3 实现随机加入逻辑除了固定房间名创建还可以让玩家先尝试随机加入一个开放房间。如果找不到再创建新房间。这样能实现“快速开始”的效果。// 文件路径Assets/Scripts/GoreboxLauncher.cs 的扩展 public void QuickStart() { PhotonNetwork.JoinRandomRoom(); } public override void OnJoinRandomFailed(short returnCode, string message) { RoomOptions options new RoomOptions { IsOpen true, IsVisible true, MaxPlayers maxPlayers }; options.CustomRoomProperties new Hashtable { { mode, sandbox } }; PhotonNetwork.CreateRoom(Gorebox_Room_ Random.Range(1000, 9999), options); }这种模式很像是“开房即玩”。在 Gorebox 的物理沙盒玩法中随机加入一个房间可以让玩家快速体验其他人的创意世界而不是每次都等待房主设置。4.4 玩家角色生成与同步当玩家加入房间后需要生成一个代表他的角色对象。PUN 2 提供了 PhotonNetwork.Instantiate 方法可以跨网络生成同一个预制体。在 Resource 文件夹中准备一个名为 PlayerGB 的预制体预制体上必须挂载 PhotonView 组件。代码逻辑如下// 文件路径Assets/Scripts/PlayerSpawner.cs using Photon.Pun; using UnityEngine; public class PlayerSpawner : MonoBehaviourPunCallbacks { public GameObject playerPrefab; public Transform[] spawnPoints; public override void OnJoinedRoom() { int index (PhotonNetwork.PlayerList.Length - 1) % spawnPoints.Length; Transform spawnPoint spawnPoints[index]; PhotonNetwork.Instantiate(playerPrefab.name, spawnPoint.position, spawnPoint.rotation); } }玩家预制体上的 PhotonView 会自动分配 ViewID并且由创建它的客户端作为 Owner。其他客户端看到的是同步后的状态。如果你的预制体不在 Resource 目录下PhotonNetwork.Instantiate 会找不到它因此建议把动态生成的角色放到 Assets/Resources 下。4.5 房主逻辑与场景加载在使用默认 PUN 模式时场景加载通常交给房主完成。进入房间后房主可以根据自定义房间属性决定加载哪张地图。public override void OnJoinedRoom() { if (PhotonNetwork.IsMasterClient) { string sceneName (string)PhotonNetwork.CurrentRoom.CustomProperties[scene]; PhotonNetwork.LoadLevel(sceneName); } }这里要理解 IsMasterClient 的含义。当前房间内的“房主”通常是第一个创建房间的玩家。他不是通常意义上的专用服务器进程而是拥有房间管理权限的客户端。比如房主可以调用 PhotonNetwork.CloseConnection 等接口管理玩家也可以决定场景切换。当房主退出房间时Photon 会把这个权限转移给另一个客户端。4.6 联调与验证将场景导出后建议本机直接运行两个客户端或者在某台 Windows 机器上运行一个客户端另一台电脑运行另一个客户端。观察控制台输出。预期流程如下客户端 A连接到 Photon Master Server → 进入大厅 → 创建房间成功 客户端 B连接到 Photon Master Server → 进入大厅 → 看到房间列表 → 加入房间两个客户端都进入后移动角色确认位置同步正常。如果出现角色乱跳一般不是连接失败而是同步频率或物理插值设置不当。可以在 PhotonView 的 Observed Components 中检查 Transform 同步是否设置正确。5. 常见问题与排查思路5.1 典型问题对照表很多联机问题在 Gorebox 和 Photon 的组合里反复出现下面给出对照表方便快速定位。问题现象常见原因解决思路一直卡在 ConnectingApp ID 未填或填错检查 PhotonServerSettings 中的 App ID能连接但看不到房间AppVersion 不一致统一所有客户端的 GameVersion加入房间超时玩家所在区域与固定 Region 距离过远改为自动选择 Region 或改用最近节点角色移动不同步预制体缺少 PhotonView给角色预制体挂载 PhotonView点击创建房间没反应房间名被占用随机房间名或加入失败后重新创建场景不切换只有房主能 LoadLevel检查 IsMasterClient 判断逻辑房间列表为空房间被设置为 IsVisiblefalse确认 RoomOptions 中可见属性服务器时间错误导致 TLS 失败系统时间与 NTP 偏差配置 NTP 时间同步并检查服务器时区5.2 四步排查流程如果遇到问题不要上来就改代码建议按顺序排查第一步确认 App ID。把 Dashboard 中的 App ID 复制出来和 Unity 配置里的字符串逐个字符对比尤其注意空格。第二步确认版本号。Photon 的 GameVersion 和应用版本是两个概念前者是 Photon 网络层版本隔离后者是游戏自己的版本号。两者都会影响匹配。第三步确认网络。本地客户端需要能够访问公网。有些办公网络或校园网默认屏蔽 UDP 端口可以尝试把 Photon 的传输协议切到 TCP 排障。第四步看日志。Unity Console 面板的日志信息已经足够定位 90% 的接入问题。打开 PhotonServerSettings 里的 Log Level把日志调成 All再看连接状态变化。5.3 如何判断 CCU 是否耗尽如果在并发较高时段出现“连接被拒绝”而配置没有变动很可能就是 CCU 用满了。进入 Photon Dashboard查看当前应用的实时并发用户数。如果长期达到上限要么增加单房间人数上限但减少房间数要么升级付费套餐。判断方法还要结合玩家行为如果房间 8 人满后第 9 个人永远进不来那是房间 MaxPlayers 限制如果是所有房间一起拒绝新连接才是 CCU 瓶颈。6. 最佳实践与工程建议6.1 房间生命周期管理在 Gorebox 这类玩法中房间可能长时间保持开放。为了避免无意义占用 CCU建议在房主断线后设定一个重试时间窗口。Photon 提供 EmptyRoomTtl 和 PlayerTtl 配置可以控制空房间和玩家短暂断线后的保留时间。不要把房间生命周期交给玩家自觉。创建房间时就设置一个合理的时间上限或者用自定义房间属性记录“最后活跃时间”当房间内没有任何玩家长时间活动时自动关闭。这样既能节省 CCU 额度也能有效避免服务器资源浪费。6.2 配置管理与灰度发布多人联机项目最忌讳所有客户端直接连同一个 App ID、同一个 GameVersion。开发环境、测试环境、生产环境要分别创建独立的 Photon 应用用 App ID 天然隔离开。当你需要灰度发布新版玩法时可以只让部分测试人员使用新的 GameVersion其余玩家继续用旧版本。因为 Photon 的房间发现依靠 GameVersion 隔离所以这两个群体的玩家互相看不到对方房间可以互不影响地测试。等验证稳定后再统一版本号。6.3 物理同步与帧率优化Gorebox 风格的物理沙盒场景里大量刚体碰撞会带来很大的同步压力。不要把所有 Rigidbody 都交给每个客户端同步否则任何一部手机或中端电脑都可能被网络包拖垮。一个可行的优化方向是玩家身边的物体高同步频率保证手感。远距离的物体降低同步频率或者只在位置变化超过阈值时同步。仅供装饰的物体完全不同步只保留静止状态。也可以把一些物理对象标记为 Kinematic然后由房主客户端计算并统一广播结果。这样玩法层的数据量会明显下降。6.4 日志、监控与安全接入 Photon 之后建议在关键节点打日志连接成功进入大厅创建房间成功加入房间失败房主转移玩家进出房这些日志不仅帮助你排错也能辅助分析玩家的活跃时段。对于玩家创建的公共房间要设置房间可见性、密码或者好友邀请机制避免陌生人随意进入捣乱。不要直接信任客户端上报的数据尤其是伤害、积分、背包等关键数值服务端校验或至少做一定程度的校验逻辑。安全边界方面要注意App ID 应该被视为公开信息但 GameVersion 和自定义规则是内部管理信息不要随意在公网论坛上张贴。如果发现异常的大量短连接可以到 Dashboard 查看请求来源必要时更换 App ID。6.5 成本与容量规划如果你的 Gorebox 房间计划长期开放给较多玩家先按照“同时在线峰值”来估算 CCU 需求。一个 8 人房间同时在线 10 个房间就是 80 CCU 峰值。免费额度如果只有 20 CCU峰值时段必然会出现拒绝连接。容量规划时还要考虑热点时间。不少服务器运营者发现晚间 20:00 到 23:00 是联机高峰期这时候可以提前观察 Dashboard 并发曲线。避免直接购买最高档套餐而是先跑一周根据曲线判断真实需求。6.6 关于自建 Photon Server 的提醒如果需求规模很大或者有严格的私有化要求可以选择在自有服务器上部署 Photon Server。它通常要求你准备一台干净的 Windows Server 或 Linux 环境开放特定 UDP/TCP 端口并规划好服务器时区、数据库、负载均衡。相比 Photon Cloud自建方案实现成本更高适合企业级项目或对数据主权有明确要求的团队。普通多人房间完全可以从 Photon Cloud 起步等量级上升后再考虑迁移。7. 总结与后续学习方向使用 Photon 托管 Gorebox 联机房间核心并不是购买一台昂贵云服务器而是理解 App ID、GameVersion、Region 和 Room 这几个概念怎么配合。第一次接入时最容易浪费时间的地方往往不是代码而是 App ID 没填对、版本号不一致、区域选择太远这类配置问题。所以我建议先从最小示例跑通两个客户端能在房间里互相看到再逐步加入地图切换、RPC 广播和物理同步优化。如果你是在开发自己的 Unity 物理沙盒游戏PUN 2 适合快速做出可玩的联机原型但要实现更精细化的大世界同步、更强反作弊能力可以继续研究 Photon Fusion 的 Host Mode 或 Server Mode。如果对延迟数据非常敏感还可以深入 Photon 的自定义区域路由和序列化压缩方案。希望这篇文章能帮你把 Gorebox 的多人房间从“局域网可用”升级到“公网可玩”的阶段。遇到连接问题时照第 5 章的排查清单按顺序查一遍大部分状况都能快速定位。收藏备用需要搭房间时直接翻到实战代码复制使用即可。
返回列表