这个模版文件能够在互联网上提供游戏大厅功能,提供用户注册、用户登录、新建房间、加入房间、准备完毕、开始游戏6个功能模块。

该模版使用Unity 2022.3.53f1c1 开发,引用了NetCode For GameObjects 1.12.2包和Localization包,并且对NetCode For GameObjects 1.12.2包里的场景管理器进行了替换,使之能够轻松支持在互联网上开房间的网络联机游戏。

游戏模版文件导出的Demo Windows平台的exe包文件: 客户端 服务端

游戏模版文件的源代码工程文件: 源代码

自定义场景管理器的NetCode For GameObjects 1.12.2包文件: 包文件
包文件下载后,打开包管理器使用从磁盘添加tarball包来安装。

Localization包,使用包管理器里的unity registry来搜索安装。

第一步 准备开发环境

准备好unity编辑器,版本号为Unity 2022.3.53f1c1。在unity hub里选择添加模块Windows Dedicated Server Build Surpport,这个模块在导出服务端的时候要用到。

第二步 下载工程文件和依赖包

下载 源代码 文件,解压,然后在unityhub里 从磁盘添加项目,把fwhas目录添加为工程项目。然后双击该项目启动unity编辑器打开工程文件。

下载 自定义netcode包 ,打开unity编辑器里的包管理器,使用 从磁盘添加tarball来添加下载到的名为com.unity.netcode.gameobjects-1.12.2.tgz 包,忽略无效证书的提示。

在unity编辑器里的包管理器,选择unity Registry,搜索Localization,搜到后点击安装。

第三步 选择导出配置

在Assets/Config目录下有一个名为Init的配置文件,点中这个文件,在检查器里可以切换StartType为Client和Server。当你想导出客户端文件的时候,在导出前选择Client。如果想导出服务端文件,在导出前选择Server,然后切换导出平台为Dedicated Server。

到这里应该可以导出服务端包和客户端包了。

第四步 运行服务端和客户端

鼠标双击运行服务端包里的fwhas.exe,这是一个命令行的程序。等他启动后消息不再滚动,然后再启动客户端包里的fwhas.exe。客户端可以多开几个测试一下联网运行的效果。

问题的提出:由于原先的场景管理器是需要同步服务端所有的场景到客户端,这适合于端对端的游戏模式,在c/s模式中并不常见。开房间游戏是需要动态创建新场景的,这个功能原先的场景管理器并不支持,需要自己实现。

改动一:因为是要实现在互联网上的游戏大厅联网游戏,所以把这个场景管理器替换成一个简单的场景管理器。在这个简单的场景管理器里,客户端只有一个场景,而服务端有许多个场景。客户端选择哪个场景,服务端就同步哪个场景。

改动二:约定所有场景具备唯一的名称,在服务端加载一个名为Active的空场景,并且设定为Active Scene。也就是说,所有动态创建的网络对象,缺省都在这个空场景里创建。创建完成后,再使用SceneManager.MoveGameObjectToScene将其移动到指定的场景里去。网络环境中,不可能大家各自指定一个活动场景,这样会导致冲突的,这样约定后,就没有冲突了。

改动三:增加了一个方法,来创建和加载并合并场景。开房间的游戏大家都知道,有一个房间创建者,新开的房间场景,就以类似”Room_玩家用户名”这样的命名方式来命名。而这个新建的场景,是以固定场景Room加载进来,再合并到一个新的名称”Room_玩家用户名”。同样,主游戏场景也是这样的过程,加载固定的Game场景,然后合并到新建的"Game_玩家用户名"场景里去。然后由场景管理器实现服务端和客户端之间的场景同步。

自定义场景管理器的实例引用为NetworkManager.Singleton.SceneManager,他的方法如下:

//服务端加载场景
//sceneName为场景名称
void SvrLoadScene(string sceneName);

// 服务端卸载场景
//sceneName场景名称
void SvrUnloadScene(string sceneName);

// 服务端创建新场景并且加载另外一个场景,然后以offset为偏移合并加载的场景到新创建的场景里去。
//id指定客户端id
//desScene目标场景名
//srcScene源场景名
//offset"场景偏移
void SvrCreateAndMergeScene(ulong id,string desScene,string srcScene,Vector3 offset);

//客户端切换当前场景
//curScene指定场景名
void ClientSwitchScene(string curScene);

// 在服务端切换某个客户端的场景
//id指定客户端id
//curScene指定场景名
void ServerSwitchScene(ulong id,string curScene);

//设置缺省场景,在客户端第一次连接到服务端的时候,服务端会同步缺省场景给客户端。
//defaultScene缺省场景名
void SetDefaultScene(string defaultScene);

//服务端场景加载完毕事件,当服务端场景加载完毕后触发。
//使用NetworkManager.Singleton.SceneManager.OnServerSceneLoadComplete += OnServerSceneLoadComplete;
//来添加事件触发函数。
OnServerSceneLoadComplete(string scname)

This template file can provide the function of the game hall on the Internet, providing six functional modules: user registration, user login, new room, join room, preparation, and game start.

The template is developed using Unity 2022.3.53f1c1, references the NetCode For GameObjects 1.12.2 package and Localization package, and replaces the scene manager in the NetCode For GameObjects 1.12.2 package, so that it can easily support online games that open rooms on the Internet.

Demo Windows platform exe package file exported from game template file: client server

Source code engineering file for game template file: Source code

NetCode For GameObjects 1.12.2 package file for custom scene manager: package file

After downloading the package file, open the package manager and install it by adding the tarball package from the disk.

Localization package, use the unity registry in the package manager to search for installation.

The first step is to prepare the development environment

Prepare the Unity Editor with version number Unity 2022.3.53f1c1. Select the Windows Dedicated Server Build Surport module in Unity Hub, which will be used when exporting to the server.

Step 2: Download the project files and dependency packages

Download the source code file, unzip it, and then add the project from the disk in Unityhub. Add the fwhas directory as the engineering project. Then double-click on the project to launch the Unity editor and open the project file.

Download the custom netcode package, open the package manager in the Unity editor, and use "Add tarball from disk" to add the downloaded package named "com. unity. netcode. gameobjects s-1.12.2. tgz", ignoring the prompt for invalid certificates.

In the package manager of the Unity editor, select Unity Registry, search for Localization, and then click Install.

Step 3: Select Export Configuration

There is a configuration file called Init in the Assets/Config directory. Click on this file and in the inspector, you can switch the StartType to Client and Server. When you want to export client files, select Client before exporting. If you want to export server files, select Server before exporting, and then switch the export platform to Dedicated Server.
You should be able to export server and client packages here.

Step 4: Run the server and client

Double click the mouse to run fwhas.exe in the server package, which is a command-line program. After he starts, the message will no longer scroll, and then start fwhas.exe in the client package. The client can open several more tests to test the effectiveness of networked operation.

Problem raised: As the original scene manager required synchronizing all scenes from the server to the client, this is suitable for end-to-end game mode and is not common in C/S mode. Opening a room game requires dynamically creating new scenes, which was not supported by the original scene manager and needs to be implemented by oneself.

Change 1: Because it is to realize online games in the game hall on the Internet, the scene manager is replaced with a simple scene manager. In this simple scene manager, the client has only one scene, while the server has many scenes. The client selects the scene, and the server synchronizes the scene accordingly.

Change 2: It is agreed that all scenes have unique names, and an empty scene named Active is loaded on the server and set as Active Scene. That is to say, all dynamically created network objects are created by default in this empty scene. After creation, use SceneManager again MoveGameObject To Scene moves it to the specified scene. In the online environment, it is impossible for everyone to specify a specific activity scenario, as this can lead to conflicts. Once agreed upon, there will be no conflicts.

Change 3: Added a method to create, load, and merge scenes. Everyone knows about the game of opening a room. There is a room creator who names newly opened room scenes using a naming convention similar to "Room_player username". And this newly created scene is loaded as a fixed scene Room and merged into a new name "Room_Player Username". Similarly, the main game scene goes through the same process, loading a fixed Game scene and merging it into the newly created "Games_Player Username" scene. Then, the scene manager implements scene synchronization between the server and client.

The instance reference for the custom scene manager is NetworkManager Singleton.SceneManager, His method is as follows:

//Server loading scenario
//SceneName is the name of the scene
void SvrLoadScene(string sceneName);

//Server uninstallation scenario
//SceneName Scene Name
void SvrUnloadScene(string sceneName);

//The server creates a new scene and loads another scene, then merges the loaded scene with offset into the newly created scene.
//ID specifies the client ID
//DesScene Target Scene Name
//SrcScene Source Scene Name
//Offset "Scene offset
void SvrCreateAndMergeScene(ulong id,string desScene,string srcScene,Vector3 offset);

//Client switches to the current scene
//CurScene specifies the scene name
void ClientSwitchScene(string curScene);

//Scenario of switching a client on the server
//ID specifies the client ID
//CurScene specifies the scene name
void ServerSwitchScene(ulong id,string curScene);

//Set the default scenario, and when the client first connects to the server, the server will synchronize the default scenario with the client.
//DefaultScene Default Scene Name
void SetDefaultScene(string defaultScene);

//The server-side scene loading completion event is triggered when the server-side scene is loaded.
//Use NetworkManager.Singleton.SceneManager.OnServerSceneLoadComplete += OnServerSceneLoadComplete;
//Add an event trigger function.
OnServerSceneLoadComplete(string scname)