URL
status
type
date
slug
summary
tag
category
password
icon
老毛说过:“与人奋斗,其乐无穷”,多人游戏之所以好玩,是因为玩家能够体验到与其他玩家之间产生联系的乐趣。我想要开发一款多人联机游戏并发布到Steam上,但不知道应该从哪些地方入手,纸面上的设计我是能做的,但是技术上还不太清楚该怎么实现,于是从网上整理了一些资料,自学!再加上个人的一些开发经验,总结!于是就有了这篇文章。
 
首先需要在UnityAssetStore上下载Mirror,然后在GitHub上下载下面的两个UnityPackage并依次导入项目中。
Steamworks.NET
rlabrecqueUpdated Nov 10, 2024
FizzySteamworks
ChykaryUpdated Nov 9, 2024

Steam Network Room Manager

先在游戏的初始界面创建一个Steam Network Room Manager的空物体,然后将下面的四个脚本添加到Steam Network Room Manager上。
Fizzy Steamworks
FizzySteamworks 是一个基于 Mirror 网络库的 Unity 插件,用于通过 Steam 网络实现多人联机功能。它支持使用 Steam 的旧版 SteamNetworking API 和新的 SteamSockets API。
Steam Manager
Steam Manager 脚本是 Steamworks.Net的一部分,主要用于在 Unity 项目中管理与 Steam 的连接。它提供了一些基本逻辑,以设置和维护与 Steam 的连接,是开发者使用 Steamworks API 的起点。
 
notion image
CustomNetworkRoomManager.cs
SteamLobby.cs
notion image
CustomNetworkRoomManager继承自NetworkRoomManager,Network Info的Transport属性是联机传输层,将Fizzy Steamworks赋给它,这表示我们将使用Steam免费提供的P2P联机。如果是Mirror官方的话,它会给一个kcp的传输层,这需要自行搭建服务器。
Offline Scene是离线场景
Online Scene是在线场景
Player Prefab是玩家对象的预制体
Room Player Prefab代表玩家的房间的预制体,
Room Scene是房间的场景,
Gameplay Scene是实际游玩的场景,
下面我们将创建它们。
 
创建房间的按钮点击时调用SteamLobby.HostLobby方法
notion image

房间场景相关

Room Player Prefab

接下来创建RoomPlayer的预制体
notion image
在Mirror框架下,所有需要网络在线同步的gameobject都需要添加一个NetworkIdentity脚本,再添加NetworkRoomPlayer脚本,代表它是房间中的玩家对象。
 
 

GameManager

还有一些UI交互的逻辑的代码:
LobbyMenuController.cs负责开始游戏的逻辑,GameMenuController.cs负责退回房间的逻辑
LobbyMenuController.cs
GameMenuController.cs

GamePlay场景相关

PlayerPrefab

PlayerPrefab是GameplayScene中玩家操控的玩家预制体,无论如何,预制体的最上层都必须要有Network Identity组件,我是将玩家所需要用到的Cinemachine作为名为Camera Group这个空物体的子物体,然后放到PlayerPre里面(之前是放在外面)。
再添加Network Transform组件,在Don’t change these at Runtime这一栏勾选同步的玩家对象的变换信息。
如果想要在游戏中显示玩家的Steam账户昵称,则需要创建玩家昵称的3DText对象,我这里命名为Player Name,再添加一个PlayerNetInfo脚本并与前者关联,储存玩家的网络信息,以显示玩家的Steam昵称。
notion image
PlayerNetInfo.cs
 
notion image
notion image

StartPosition

StartPosition是Gameplay Scene中玩家的出生点,根据你需要玩家出生的位置,朝向,在场景中创建即可,出生点只需要添加一个Network Start Position组件,就代表了玩家的出生点。当然,也可以有多个出生点,如果一个场景中有多个出生点,那么系统将会随机选择一个,在此位置生成玩家预制体Player Prefab

NetworkManager

在Gameplay Scene中创建一个空物体NetworkManager,并给其添加上下面这三个组件
notion image

其他需要同步的物体

游戏中可能还会出现其他需要同步的物体,比如说一些可破坏物,可移动的物体,它们应该无一例外地被添加上Network Identity组件,如果需要同步变换信息(位置,旋转,大小),则需要添加Network Transform组件,玩家对象通常是需要同步的,这里的同步是指不同的玩家都接收到相同的信息,所以摄像机是不同步的,因为每个玩家都有各自的视角。
 

打包测试

打包测试时,首先要确保场景的进入顺序是正确的
notion image
在测试之前,需要在游戏的顶层文件夹中创建一个名为steam_appid的txt文件,然后填入480即可。
480是steam提供的一个免费的测试接口,对应的是spacewar这个游戏,如果使用注册了steam开发者的账户去测试,则不需要这个txt文件。

总结

这些功能还很基础,适用于像《泰拉瑞亚》这样的弱联机玩法。一旦有一个需要,做一个联机房间,疑惑是匹配联机的功能,真的做好,还是得花上一番心思的,接下来我将理清如果要达到现代水平的pvp游戏,大致有哪些功能性需求。
就拿一个正常水平的服务型多人游戏来举例,就比如说鹅厂做的某款pvp游戏,它的联机方式有两种选择,一种是联机大厅,如果是大型网游的话,大厅可以是不唯一的,里面有玩家创建的联机房,玩家在联机大厅中选择并点击想要进入的房间。
房间支持设置密码,聊天,还能够选择Gameplay的一些属性。
在这一整个系统里,房主的职能有:创建房间,配置房间属性,在聊天区输出信息,选择是否踢出玩家,解散房间,等到房间中的所有玩家都准备好之后,点击开始游戏。
其他玩家的职能有:加入房间,准备,在聊天区输出信息。
notion image
notion image
至于说局内的玩家数据同步,则要涉及到更多的地方,对局结尾还可能需要根据玩家的表现进行评价,这有需要去读取玩家们在gameplay过程中的数据,构建一个较为完整的多人联机游戏所需要的工作远不止这些,想想还是不容易,我要去补一下计算机网络的基础知识了(/ω\)。
封装继承中遗忘,底层逻辑中深刻元宇宙何时能丢掉噱头的帽子?
Loading...