适用于 Unity 的 Multiplay Hosting SDK
Integrate Multiplay Hosting functionality into your Unity game server.
阅读时间10 分钟最后更新于 15 天前
适用于 Unity 的 Multiplay Hosting SDK 具备全部所需功能,以供您在游戏中使用 Multiplay Hosting 缩放和游戏服务器服务。
Unity.Services.Multiplay要求和限制
适用于 Unity 的 Multiplay Hosting SDK 兼容 Unity 编辑器 2020.3 及更高版本。初始化 SDK
使用实例方法创建IMultiplayServiceasync void Example_InitSDK(){ try { await UnityServices.InitializeAsync(); } catch (Exception e) { Debug.Log(e); }}
配置游戏服务器
ServerConfigServerConfigServerConfigServerConfigServerConfig参数 | 类型 | 描述 |
|---|---|---|
| long | 服务器 ID。 |
| 字符串 | 分配 ID。 |
| ushort | 服务器查询协议端口编号。 |
| ushort | 游戏会话的连接端口。这是游戏客户端可用以连接游戏会话的端口编号。 |
| 字符串 | 游戏服务器保存日志文件的目录。 |
ServerConfigusing System.Collections;using System.Collections.Generic;using Unity.Services.Multiplay;using UnityEngine;public class Example_ServerConfiguration{ /// <summary> /// A simple example of accessing each of the server config's fields and printing them to the debug console. /// </summary> public static void LogServerConfig() { var serverConfig = MultiplayService.Instance.ServerConfig; Debug.Log($"Server ID[{serverConfig.ServerId}]"); Debug.Log($"AllocationID[{serverConfig.AllocationId}]"); Debug.Log($"Port[{serverConfig.Port}]"); Debug.Log($"QueryPort[{serverConfig.QueryPort}"); Debug.Log($"LogDirectory[{serverConfig.ServerLogDirectory}]"); }}
游戏服务器准备就绪
使用ReadyServerForPlayersAsyncusing System.Threading.Tasks;using Unity.Services.Multiplay;/// <summary>/// Ready the server. This is to indicate that the server is ready to accept players./// Readiness is the server's way of saying it's ready for players to join the server./// You must wait until you have been Allocated before you can call ReadyServerForPlayersAsync./// </summary>private async void Example_ReadyingServer(){ // After the server is back to a blank slate and ready to accept new players await MultiplayService.Instance.ReadyServerForPlayersAsync();}
游戏服务器未就绪
使用UnreadyServerAsyncusing System.Threading.Tasks;using Unity.Services.Multiplay;/// <summary>/// Unready the server. This is to indicate that the server is in some condition which means it can't accept players./// For example, after a game has ended and you need to reset the server to prepare for a new match./// </summary>private async void Example_UnreadyingServer(){ // The match has ended and players are disconnected from the server await MultiplayService.Instance.UnreadyServerAsync();}
启动服务器查询处理程序
使用StartServerQueryHandlerAsync参数 | 类型 | 描述 |
|---|---|---|
| ushort | 服务器上可以存在的最大玩家人数。 |
| 字符串 | 服务器的名称。 |
| 字符串 | 服务器所运行游戏类型的名称或标识符。 |
| 字符串 | 游戏的版本。 |
| 字符串 | 服务器正在运行的游戏地图或世界。 |
| ushort | 供游戏客户端用来连接游戏服务器的端口编号。 |
StartServerQueryHandlerAsyncparametersIServerCheckManagerUpdateServerCheck()UpdateServerCheck()
以下示例展示如何启动服务器查询处理程序。
using System.Collections;using System.Collections.Generic;using UnityEngine;using Unity.Services.Multiplay;/// <summary>/// An example of how to use SQP from the server using the Multiplay SDK./// The ServerQueryHandler reports the given information to the Multiplay Service./// </summary>public class Example_ServerQueryHandler : MonoBehaviour{ private const ushort k_DefaultMaxPlayers = 10; private const string k_DefaultServerName = "MyServerExample"; private const string k_DefaultGameType = "MyGameType"; private const string k_DefaultBuildId = "MyBuildId"; private const string k_DefaultMap = "MyMap"; public ushort currentPlayers; private IServerQueryHandler m_ServerQueryHandler; private async void Start() { m_ServerQueryHandler = await MultiplayService.Instance.StartServerQueryHandlerAsync(k_DefaultMaxPlayers, k_DefaultServerName, k_DefaultGameType, k_DefaultBuildId, k_DefaultMap); } private void Update() { m_ServerQueryHandler.UpdateServerCheck(); } public void ChangeQueryResponseValues(ushort maxPlayers, string serverName, string gameType, string buildId) { m_ServerQueryHandler.MaxPlayers = maxPlayers; m_ServerQueryHandler.ServerName = serverName; m_ServerQueryHandler.GameType = gameType; m_ServerQueryHandler.BuildId = buildId; } public void PlayerCountChanged(ushort newPlayerCount) { m_ServerQueryHandler.CurrentPlayers = newPlayerCount; }}
订阅服务器事件
使用SubscribeToServerEventsAsyncOnAllocateOnDeallocateOnErrorusing System;using System.Collections;using System.Collections.Generic;using Unity.Services.Multiplay;using UnityEngine;/// <summary>/// An example of how to access and react to multiplay server events./// </summary>public class Example_ServerEvents : MonoBehaviour{ private MultiplayEventCallbacks m_MultiplayEventCallbacks; private IServerEvents m_ServerEvents; /// <summary> /// This should be done early in the server's lifecycle, as you'll want to receive events as soon as possible. /// </summary> private async void Start() { // We must first prepare our callbacks like so: m_MultiplayEventCallbacks = new MultiplayEventCallbacks(); m_MultiplayEventCallbacks.Allocate += OnAllocate; m_MultiplayEventCallbacks.Deallocate += OnDeallocate; m_MultiplayEventCallbacks.Error += OnError; m_MultiplayEventCallbacks.SubscriptionStateChanged += OnSubscriptionStateChanged; // We must then subscribe. m_ServerEvents = await MultiplayService.Instance.SubscribeToServerEventsAsync(m_MultiplayEventCallbacks); }// Handle Multiplay events.}
处理 Multiplay Hosting 事件
MultiplayEventCallbacksOnAllocateOnDeallocateOnErrorusing System;using System.Collections;using System.Collections.Generic;using Unity.Services.Multiplay;using UnityEngine;/// <summary>/// An example of how to access and react to multiplay server events./// </summary>public class Example_ServerEvents : MonoBehaviour{ private MultiplayEventCallbacks m_MultiplayEventCallbacks; private IServerEvents m_ServerEvents; /// <summary> /// This should be done early in the server's lifecycle, as you'll want to receive events as soon as possible. /// </summary> private async void Start() { // We must first prepare our callbacks like so: m_MultiplayEventCallbacks = new MultiplayEventCallbacks(); m_MultiplayEventCallbacks.Allocate += OnAllocate; m_MultiplayEventCallbacks.Deallocate += OnDeallocate; m_MultiplayEventCallbacks.Error += OnError; m_MultiplayEventCallbacks.SubscriptionStateChanged += OnSubscriptionStateChanged; // We must then subscribe. m_ServerEvents = await MultiplayService.Instance.SubscribeToServerEventsAsync(m_MultiplayEventCallbacks); } /// <summary> /// Handler for receiving the allocation multiplay server event. /// </summary> /// <param name="allocation">The allocation received from the event.</param> private void OnAllocate(MultiplayAllocation allocation) { // Here is where you handle the allocation. // This is highly dependent on your game, however this would typically be some sort of setup process. // Whereby, you spawn NPCs, setup the map, log to a file, or otherwise prepare for players. // After you the allocation has been handled, you can then call ReadyServerForPlayersAsync()! } /// <summary> /// Handler for receiving the deallocation multiplay server event. /// </summary> /// <param name="deallocation">The deallocation received from the event.</param> private void OnDeallocate(MultiplayDeallocation deallocation) { // Here is where you handle the deallocation. // This is highly dependent on your game, however this would typically be some sort of teardown process. // You might want to deactivate unnecessary NPCs, log to a file, or perform any other cleanup actions. } /// <summary> /// Handler for receiving the error multiplay server event. /// </summary> /// <param name="error">The error received from the event.</param> private void OnError(MultiplayError error) { // Here is where you handle the error. // This is highly dependent on your game. You can inspect the error by accessing the error.Reason and error.Detail fields. // You can change on the error.Reason field, log the error, or otherwise handle it as you need to. } /// <summary> /// /// </summary> /// <param name="state"></param> private void OnSubscriptionStateChanged(MultiplayServerSubscriptionState state) { switch (state) { case MultiplayServerSubscriptionState.Unsubscribed: /* The Server Events subscription has been unsubscribed from. */ break; case MultiplayServerSubscriptionState.Synced: /* The Server Events subscription is up to date and active. */ break; case MultiplayServerSubscriptionState.Unsynced: /* The Server Events subscription has fallen out of sync, the subscription tries to automatically recover. */ break; case MultiplayServerSubscriptionState.Error: /* The Server Events subscription has fallen into an errored state and won't recover automatically. */ break; case MultiplayServerSubscriptionState.Subscribing: /* The Server Events subscription is trying to sync. */ break; } }}
分配
使用public event Action<MultiplayAllocation> Allocate;
AllocateMultiplayAllocation取消分配
使用public event Action<MultiplayDeallocation> Deallocate;
DeallocateMultiplayDeallocation错误
使用public event Action<MultiplayError> Error;
ErrorMultiplayErrorSubscriptionStateChange
使用public event Action<MultiplayServerSubscriptionState> SubscriptionStateChanged;
SubscriptionStateChangedMultiplayServerSubscriptionState使用 Unity 编辑器部署资源
使用 Multiplay Authoring 模块(与 Multiplay 包一起安装),您可以选择直接在 Unity 编辑器中创作和修改资源。然后,您可以使用 Deployment 包将资源从 Unity 编辑器上传到 Dashboard(后台)。 Unity 编辑器中存在的 Multiplay 配置允许用户将其源代码控制视为单一可信来源(而非云端版本),从而简化回滚、分割和其他常见操作。设置 Multiplay
在 Unity 编辑器中使用 Multiplay:安装所需的包
要在编辑器中创建 Multiplay 配置,请安装以下包:- Deployment
- Multiplay:
- 对于 Unity 6 及更高版本:多人游戏
- 对于 Unity 2022 LTS 及更低版本:Multiplay
安装这些包并将它们添加到可用包列表中:
- 在 Unity 编辑器中,选择 Window(窗口)> Package Manager(包管理器)。
- 选择 + > Install package by name(按名称安装包)。
- 输入 。
com.unity.services.deployment - 选择 Install(安装)。
- 对 Multiplay 重复以上步骤:
- 对于 Unity 6 及更高版本:
com.unity.services.multiplayer - 对于 Unity 2022 LTS 及更低版本:
com.unity.services.multiplay
- 对于 Unity 6 及更高版本:
关联项目
将 Unity Gaming Services(Unity 游戏服务)项目与 Unity 编辑器关联。您可以在 Unity Dashboard(Unity 后台)中找到您的 UGS Project ID。- 在 Unity 编辑器中,选择 Edit(编辑)> Project Settings(项目设置)> Services(服务)。
- 关联您的项目。
- 如果项目没有 Unity Project ID:
- 选择 Create a Unity Project ID(创建 Unity Project ID)> Organizations(组织),然后从下拉菜单中选择一个组织。
- 选择 Create project ID(创建 Project ID)。
- 如果已有 Unity Project ID:
- 选择 Use an existing Unity project ID(使用现有 Unity Project ID)。
- 从下拉菜单中选择组织和项目。
- 选择 Link project ID(关联 Project ID)。
UnityEditor.CloudProjectSettings.projectId在 Unity 编辑器中创作
借助 Multiplay Authoring 模块,您可以直接在 Unity 编辑器中创建、编辑和部署 Multiplay 配置。创建配置
按照以下步骤使用 Multiplay Authoring 模块创建 Multiplay 配置:- 在 Unity 编辑器的 Project(项目)窗口中右键单击,然后选择 Create(创建)> Services(服务)> Multiplay Config(Multiplay 配置)。
- 为资源文件命名。
- 按 Enter(输入)。
编辑配置
目前有一种方法可以编辑现有配置:- 在 Project(项目)选项卡中,双击现有资源,然后选择任何文本编辑器来编辑配置。
资源文件内容
在 Deployment(部署)窗口查找资源并根据其文件扩展名分配类型。 该配置使用yaml.gshnew_multiplay_config.gsh该配置在文件中描述了 3 个组成部分:version: 1.0builds: my build: # replace with the name for your build executableName: Build.x86_64 # the name of your build executable buildPath: Builds/Multiplay # the location of the build filesbuildConfigurations: my build configuration: # replace with the name for your build configuration build: my build # replace with the name for your build queryType: sqp # sqp or a2s, delete if you do not have logs to query binaryPath: Build.x86_64 # the name of your build executable commandLine: -port $$port$$ -queryport $$query_port$$ -log $$log_dir$$/Engine.log # launch parameters for your server variables: {} cores: 1 # number of cores per server speedMhz: 750 # launch parameters for your server memoryMiB: 800 # launch parameters for your serverfleets: my fleet: # replace with the name for your fleet buildConfigurations: - my build configuration # replace with the names of your build configuration regions: North America: # North America, Europe, Asia, South America, Australia minAvailable: 0 # minimum number of servers running in the region maxServers: 1 # maximum number of servers running in the region