本部分提供有关将 PlayFab 与 Photon 多人游戏服务(如 Photon RealTime 和 Photon Unity 网络 (PUN))一起使用的信息。
目前,我们提供以下 Photon 集成:
- 使用 PlayFab 对 Photon 玩家进行身份验证。
- 使用 PlayFab CloudScript 回调侦听房间事件。
Photon 快速入门
本快速入门介绍如何设置 Photon 多人游戏以使用 PlayFab。 当前,PlayFab 提供以下 Photon 集成:
- 使用 PlayFab 对 Photon 玩家进行身份验证。
- 使用 PlayFab CloudScript 回调侦听房间事件。
在此快速入门中,我们会使用最新的 Photon Unity 示例项目说明这两个功能如何工作。
注意
有关 Unity 上完全支持的 PlayFab 多人游戏和聊天体验,请参阅 PlayFab Party Unity 插件了解详细信息。
先决条件
- 一个 Unity 项目,其中导入了 PlayFab SDK 并具有已配置的游戏。
- 已注册 PlayFab 游戏。
注意
本指南省略了聊天应用程序设置。 若要集成聊天应用程序,请创建新的 Photon 聊天应用程序,然后在 Unity 和 PlayFab Game Manager - Photon 加载项页面对应的框中输入应用 ID。
设置 Photon 应用程序
- 注册并登录到 Photon 仪表板后,请选择“创建新应用”。
- 选择 Photon 类型。
- 选择 Name。
- 创建 Description。
- 通过选择 Create 进行提交。
设置身份验证
- 在列表中查找新创建的应用程序,然后选择“管理”。
- 在“应用程序”仪表板中,查找并保存位于“游戏”页面下的“应用 ID”。
- 找到 Authentication 部分。
- 选择“自定义服务器”。
下一个页面可用于为 Photon 配置身份验证 URL。
https://{PlayFabTitleId}.playfabapi.com/photon/authenticate
将 PlayFabTitleId
占位符替换为您自己的游戏 ID。
{PlayFabTitleId}
- 输入 URL。
- 通过选择“创建”按钮进行提交。
为 Photon 设置 PlayFab 游戏
导航到游戏的 Game Manager 页面,然后:
- 导航到 Add-ons 选项卡。
- 在附加内容列表中,找到并选择 Photon。
- 在“Photon 加载项”页面中,通过指定 Photon 实时应用程序 ID 可以安装 Photon。
- 可以选择指定 Chat App ID。
- 安装加载项 (3) 后,会生成 Photon 密钥(2)。
- 保存它以便在以后配置 Webhook 时使用。
注意
请注意将 Photon 密钥保存在安全且易于访问的位置。 配置 Webhook 时会十分方便。
设置 Photon Webhook
作为可选集成,Photon 可以将特定事件传输给 PlayFab CloudScript。 以下操作是使用 Webhook 完成的:
- 指定基 URL。
- 然后为每个可用事件指定路径。
- 路径实际上是在 CloudScript 中实现的处理程序名称。
基本 URL 具有以下格式:
https://{PlayFabTitleId}.playfablogic.com/webhook/1/prod/{PhotonSecretKey}
确保将 Title Id
占位符替换为您自己的游戏 ID。
{PlayFabTitleId}
确保将 PhotonSecretKey
令牌替换为 Photon Add-on 页面上生成的密钥。
{PhotonSecretKey}
- 填写基 URL。
- 为每个可用事件 分配 CloudScript 处理程序名称。
- 移除任何 CustomHttpHeaders 。
- 通过选择 Save 按钮提交此信息。
设置 Unity 项目
本指南假设已导入、设置了 PlayFab SDK,并配置了游戏设置。
- 首先导航到 Asset Store。
- 找到 Photon Unity Networking Free 程序包。
- 选择 Import (1)。
- 可以检查导入的文件。
- 然后选择 Import (2)。
导入过程完成之后,“PUN 设置”窗口立即打开。
- 输入在 Photon 应用程序仪表板中对所创建的 Photon 应用找到的实时应用程序 ID (1)。
- 选择 Setup Project (2)。
- 设置完成后,选择 Close (3)。
如果接受了 AppId,则“Photon 服务器设置”对象在“Unity Inspector”窗口中处于选中状态并且可供查看。 手动访问服务器设置对象:
- 导航到顶部窗口面板。
- 选择 Window。
- 然后选择 Photon Unity Networking (1)。
- 最后选择 Highlight Server Settings (2)。
- “标准 Unity”项目窗口会显示“PhotonServerSettings (3)”对象。
- 选择该对象以在 Unity Inspector 窗口中显示其设置。
注意
作为 PhotonServerSettings 的一部分,可以选择分配聊天应用程序 ID。
此时已配置了项目。
实现 PlayFab 到 Photon 的身份验证
在 PlayFab Game Manager 中为游戏启用了 Photon 加载项,并且在 Photon 应用程序仪表板上配置了身份验证后,PlayFab 允许在 Photon 环境中对现有 PlayFab 玩家进行身份验证。
这意味着可以完全避免为 Photon 实现任何用户管理。
- 从 Photon Unity Networking Free 程序包 Classic 版本导航到DemoHub-Scene-V2 场景。
- 此场景是该程序包中所有示例的中心。
- 因为它是要加载的第一个 场景,因此我们添加了一个小脚本,以便可以使用 Photon 对 PlayFab 进行身份验证。
- 创建名为 PlayFabAuthenticator 的空 GameObject。
- 然后在 Unity Inspector 窗口中,将具有相同名称的组件添加到此 GameObject。
选择齿轮图标,然后从下拉菜单中选择要编辑的脚本。 复制并粘贴 PlayFabAuthenticator
组件的代码,然后保存并关闭文件。
using PlayFab;
using PlayFab.ClientModels;
using UnityEngine;
public class PlayFabAuthenticator : MonoBehaviour {
private string _playFabPlayerIdCache;
//Run the entire thing on awake
public void Awake() {
AuthenticateWithPlayFab();
}
/*
* Step 1
* We authenticate a current PlayFab user normally.
* In this case we use the LoginWithCustomID API call for simplicity.
* You can absolutely use any Login method you want.
* We use PlayFabSettings.DeviceUniqueIdentifier as our custom ID.
* We pass RequestPhotonToken as a callback to be our next step, if
* authentication was successful.
*/
private void AuthenticateWithPlayFab(){
LogMessage("PlayFab authenticating using Custom ID...");
PlayFabClientAPI.LoginWithCustomID(new LoginWithCustomIDRequest()
{
CreateAccount = true,
CustomId = PlayFabSettings.DeviceUniqueIdentifier
}, RequestPhotonToken, OnPlayFabError);
}
/*
* Step 2
* We request a Photon authentication token from PlayFab.
* This is a crucial step, because Photon uses different authentication tokens
* than PlayFab. Thus, you cannot directly use PlayFab SessionTicket and
* you need to explicitly request a token. This API call requires you to
* pass a Photon App ID. The App ID may be hard coded, but in this example,
* we are accessing it using convenient static field on PhotonNetwork class.
* We pass in AuthenticateWithPhoton as a callback to be our next step, if
* we have acquired the token successfully.
*/
private void RequestPhotonToken(LoginResult obj) {
LogMessage("PlayFab authenticated. Requesting photon token...");
//We can player PlayFabId. This will come in handy during next step
_playFabPlayerIdCache = obj.PlayFabId;
PlayFabClientAPI.GetPhotonAuthenticationToken(new GetPhotonAuthenticationTokenRequest()
{
PhotonApplicationId = PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime
}, AuthenticateWithPhoton, OnPlayFabError);
}
/*
* Step 3
* This is the final and the simplest step. We create a new AuthenticationValues instance.
* This class describes how to authenticate a player inside the Photon environment.
*/
private void AuthenticateWithPhoton(GetPhotonAuthenticationTokenResult obj) {
LogMessage("Photon token acquired: " + obj.PhotonCustomAuthenticationToken + " Authentication complete.");
//We set AuthType to custom, meaning we bring our own, PlayFab authentication procedure.
var customAuth = new Photon.Realtime.AuthenticationValues { AuthType = CustomAuthenticationType.Custom };
//We add "username" parameter. Do not let it confuse you: PlayFab is expecting this parameter to contain player PlayFab ID (!) and not username.
customAuth.AddAuthParameter("username", _playFabPlayerIdCache); // expected by PlayFab custom auth service
//We add "token" parameter. PlayFab expects it to contain Photon Authentication Token issues to your during previous step.
customAuth.AddAuthParameter("token", obj.PhotonCustomAuthenticationToken);
//We finally tell Photon to use this authentication parameters throughout the entire application.
PhotonNetwork.AuthValues = customAuth;
}
private void OnPlayFabError(PlayFabError obj) {
LogMessage(obj.GenerateErrorReport());
}
public void LogMessage(string message) {
Debug.Log("PlayFab + Photon Example: " + message);
}
}
测试 PlayFab 到 Photon 的身份验证
- 启动场景。
- 检查控制台消息流。 控制:
- 对 PlayFab 本身进行的身份验证是否成功。
- 是否获取了 Photon 令牌。
下图说明正确的流程。
获取了 Photon 令牌,并且身份验证完成后,便可以签出 Photon 演示。
例如,启动名为 Demo Boxes 的演示。
- 为确保 PlayFab 身份验证完成,请选择 Demo Boxes。
- 然后选择 Load Dem,如下图所示。
Photon 开始输出调试消息。 通过监视控制台,可以轻松查明是否遇到任何身份验证问题。
确保控制台中不存在 Authentication Denied 错误。 此时已设置了最低程度的 PlayFab 与 Photon 集成。
Photon 房间事件 + CloudScript
Photon 匹配系统具有房间 的概念。 如果不熟悉此概念,请参阅 Photon 匹配指南。
PlayFab 允许截获各种房间事件。 以下房间事件只需 CloudScript 即可截获:
RoomCreated
RoomJoined
RoomLeft
RoomClosed
以下事件需要对 Unity 代码进行额外控制才能进行截获(本文档后面部分提供了详细信息):
RoomPropertyUpdated
RoomEventRaised
注意
引入房间事件的处理程序后,它成为事件处理流的必要组成部分。 因此,在运行 CloudScript 时产生的错误可能会导致整个 系统出现问题。 例如,如果 RoomCreated
处理程序引发错误,则客户端也会引发错误,并且无法正确连接。
我们通过为每种事件类型分别定义处理程序,来构造一个 PlayFab CloudScript。
创建房间处理程序
每当创建 Photon 房间时,都会调用 RoomCreated
处理程序。 以下 CloudScript 处理程序会截获这类事件。
// Triggered automatically when a Photon room is first created
handlers.RoomCreated = function (args) {
return { ResultCode : 0, Message: 'Success' };
};
注意
使用“args”参数可以获取有关事件的更多数据。
{
"ActorNr": 1,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Options with which the room was created.
"CreateOptions": {
"MaxPlayers": 4,
"LobbyId": null,
"LobbyType": 0,
"CustomProperties": {
},
"EmptyRoomTTL": 0,
"PlayerTTL": 0,
"CheckUserOnJoin": false,
"DeleteCacheOnLeave": true,
"SuppressRoomEvents": false,
"PublishUserId": false,
"ExpectedUsers": null
},
// Unique game identifier
"GameId": "8b8322de-096d-4481-a2b2-8db8bb45cfef",
"Region": "EU",
"Type": "Create",
// User that caused the room to be created
"UserId": "834D5AA5BAB1DFB6",
"Username": ""
}
加入房间处理程序
每当玩家加入房间时,都会调用 RoomJoined
处理程序。 以下 CloudScript 处理程序会截获这类事件。
// Triggered automatically when a player joins a Photon room
handlers.RoomJoined = function (args) {
return { ResultCode : 0, Message: 'Success' };
};
对于进入房间的第一个用户,不调用此回调。 使用 RoomCreated
可截获加入的第一个玩家。 使用“args”参数可以获取有关事件的更多数据。
{
"ActorNr": 2,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Unique Game Identifier
"GameId": "b0f55a2e-431d-402a-9809-b0240443267e",
"Region": "EU",
"Type": "Join",
// Id of the player that has joined
"UserId": "AAC7634BF46289DF",
"Username": ""
}
离开房间
每当玩家离开房间时,都会调用 RoomLeft
处理程序。 以下 CloudScript 处理程序会截获这类事件。
// Triggered automatically when a player leaves a Photon room
handlers.RoomLeft = function (args) {
return { ResultCode : 0, Message: 'Success' };
};
使用“args”参数可以获取有关事件的更多数据。
{
"ActorNr": 2,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Unique Game Identifier
"GameId": "b0f55a2e-431d-402a-9809-b0240443267e",
"IsInactive": false,
"Reason": "0",
"Region": "EU",
"Type": "ClientDisconnect",
// Id of the user that has left the room
"UserId": "AAC7634BF46289DF",
"Username": ""
}
关闭房间处理程序
每当最后一个玩家离开房间,房间中没有任何玩家留下时,都会调用 RoomClosed
处理程序。 以下 CloudScript 处理程序会截获这类事件。
// Triggered automatically when a Photon room closes
// Note: currentPlayerId is undefined in this function
handlers.RoomClosed = function (args) {
return { ResultCode : 0, Message: 'Success' };
};
使用“args”参数可以获取有关事件的更多数据。
"ActorCount": 0,
"ActorNr": 1,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Unique game identifier
"GameId": "b0f55a2e-431d-402a-9809-b0240443267e",
"Region": "EU",
"State2": {
"ActorList": [
]
},
"Type": "Close"
}
更新房间属性
每当房间属性更改时,都会调用 RoomPropertyUpdated
处理程序。 以下 CloudScript 处理程序会截获这类事件。
// Triggered automatically when a Photon room game property is updated.
// Note: currentPlayerId is undefined in this function
handlers.RoomPropertyUpdated = function (args) {
return { ResultCode : 0, Message: 'Success' };
};
注意
currentPlayerId
未在此处理程序中定义。 如果从客户端更改了房间属性,则可以使用“args”参数,并引用 UserId 以获取负责的玩家。
使用“args”参数可以获取有关事件的更多数据。
{
"ActorNr": 1,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Custom Room Properties
"Properties": {
"CustomProperty": "It's Value"
},
"GameId": "8b8322de-096d-4481-a2b2-8db8bb45cfef",
"Region": "EU",
"State": {
"ActorCounter": 1,
"ActorList": [
{
"ActorNr": 1,
"UserId": "834D5AA5BAB1DFB6",
"Username": "",
"IsActive": true,
"Binary": "RGIAAAEBRAAAAAFi\/3MAAA==",
"DEBUG_BINARY": {
"1": {
"255": ""
}
}
}
],
"Binary": {
"18": "RAAAAANi+nkAAHNzAA1QbGF5ZXJJbmRleGVzRGlpAAEAAAABAAAAAHMADkN1c3RvbVByb3BlcnR5cwAKSXQncyBWYWx1ZQ=="
},
"CheckUserOnJoin": false,
"CustomProperties": {
},
"DeleteCacheOnLeave": true,
"EmptyRoomTTL": 0,
"IsOpen": true,
"IsVisible": true,
"LobbyType": 0,
"LobbyProperties": [
],
"MaxPlayers": 4,
"PlayerTTL": 0,
"SuppressRoomEvents": false,
"Slice": 0,
"DebugInfo": {
"DEBUG_PROPERTIES_18": {
"250": [
],
"PlayerIndexes": {
"1": 0
},
"CustomProperty": "It's Value"
}
},
"ExcludedActors": [
],
"PublishUserId": false,
"ExpectedUsers": [
]
},
"Type": "Game",
"UserId": "834D5AA5BAB1DFB6",
"Username": ""
}
使用 Unity Photon 客户端更改自定义房间属性时,请务必标记调用,以便它将事件传递给 Webhook(在此例中为 PlayFab)。
// Properties updates ( this hashtable contains the properties to be changed. Properties not mentioned here will stay as is
var properties = new ExitGames.Client.Photon.Hashtable() { { "CustomProperty" , "It's Value" } };
// Control set. Empty in this case, because our property has not existed before.
// Otherwise you would include previous value of the property.
var expectedProperties = new ExitGames.Client.Photon.Hashtable();
// Set Custom Properties call. Notice the last argument set to "true"
// This tells Photon to forward event to the webhook.
PhotonNetwork.room.SetCustomProperties(properties, expectedProperties, true);
引发房间事件
每当引发自定义房间事件时,会调用 RoomEventRaised。 以下 CloudScript 处理程序会截获这类事件。
// Triggered by calling "OpRaiseEvent" on the Photon client. The "args.Data" property is
// set to the value of the "customEventContent" HashTable parameter, so you can use
// it to pass in arbitrary data.
handlers.RoomEventRaised= function (args) {
return { ResultCode : 0, Message: 'Success' };
};
使用“args”参数可以获取有关事件的更多数据。
{
"ActorNr": 1,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Custom event data
"Data": {
"Hello": "World"
},
"GameId": "8b8322de-096d-4481-a2b2-8db8bb45cfef",
"Region": "EU",
"State": {
"ActorCounter": 1,
"ActorList": [
{
"ActorNr": 1,
"UserId": "834D5AA5BAB1DFB6",
"Username": "",
"IsActive": true,
"Binary": "RGIAAAEBRAAAAAFi\/3MAAA==",
"DEBUG_BINARY": {
"1": {
"255": ""
}
}
}
],
"Binary": {
"18": "RAAAAAJi+nkAAHNzAA1QbGF5ZXJJbmRleGVzRGlpAAEAAAABAAAAAA=="
},
"CheckUserOnJoin": false,
"CustomProperties": {
},
"DeleteCacheOnLeave": true,
"EmptyRoomTTL": 0,
"IsOpen": true,
"IsVisible": true,
"LobbyType": 0,
"LobbyProperties": [
],
"MaxPlayers": 4,
"PlayerTTL": 0,
"SuppressRoomEvents": false,
"Slice": 0,
"DebugInfo": {
"DEBUG_PROPERTIES_18": {
"250": [
],
"PlayerIndexes": {
"1": 0
}
}
},
"ExcludedActors": [
],
"PublishUserId": false,
"ExpectedUsers": [
]
},
"Type": "Event",
// PlayFab User Id if he/she was the source of the event
"UserId": "834D5AA5BAB1DFB6",
"Username": "",
// Event code
"EvCode": 15
}
使用 Unity Photon 客户端引发自定义房间事件时,请务必标记调用,以便它将事件传递给 Webhook(在此例中为 PlayFab)。
var data = new Dictionary<string,object>() {
{ "Hello" , "World" }
};
// Raise custom room event
// Replace 15 with any custom event code of your choice [0..299]
PhotonNetwork.RaiseEvent(15, data, true, new RaiseEventOptions() {
ForwardToWebhook = true, // Mark call to pass event to Webhook (PlayFab in this case)
});
测试房间事件处理程序
此示例扩展上一个示例(PlayFab + Photon 身份验证)。
为游戏上传以下 CloudScript。
handlers.RoomCreated = function (args) {
server.WriteTitleEvent({
EventName : "room_created"
});
return { ResultCode : 0, Message: 'Success' };
};
handlers.RoomJoined = function (args) {
server.WriteTitleEvent({
EventName : "room_joined"
});
return { ResultCode : 0, Message: 'Success' };
};
handlers.RoomLeft = function (args) {
server.WriteTitleEvent({
EventName : "room_left"
});
return { ResultCode : 0, Message: 'Success' };
};
handlers.RoomClosed = function (args) {
server.WriteTitleEvent({
EventName : "room_closed"
});
return { ResultCode : 0, Message: 'Success' };
};
handlers.RoomPropertyUpdated = function (args) {
server.WriteTitleEvent({
EventName : "room_property_changed"
});
return { ResultCode : 0, Message: 'Success' };
};
handlers.RoomEventRaised = function (args) {
server.WriteTitleEvent({
EventName : "room_event_raised"
});
return { ResultCode : 0, Message: 'Success' };
};
该代码仅是在每次调用 Photon 回调时发布新游戏事件。 此示例在生产中没有用处,只是为了让我们清楚了解回调的调用方式。
通过包含会引发自定义事件的新示例代码来扩展 PlayFabAuthenticator
脚本,并设置自定义房间属性。 扩展版本也利用 Awake
方法,不会在场景加载之间销毁对象。
using System.Collections.Generic;
using PlayFab;
using PlayFab.ClientModels;
using UnityEngine;
public class PlayFabAuthenticator : MonoBehaviour {
private string _playFabPlayerIdCache;
//Run the entire thing on awake
public void Awake() {
AuthenticateWithPlayFab();
DontDestroyOnLoad(gameObject);
}
/*
* Step 1
* We authenticate a current PlayFab user normally.
* In this case we use the LoginWithCustomID API call for simplicity.
* You can absolutely use any Login method you want.
* We use PlayFabSettings.DeviceUniqueIdentifier as our custom ID.
* We pass RequestPhotonToken as a callback to be our next step, if
* authentication was successful.
*/
private void AuthenticateWithPlayFab() {
LogMessage("PlayFab authenticating using Custom ID...");
PlayFabClientAPI.LoginWithCustomID(new LoginWithCustomIDRequest()
{
CreateAccount = true,
CustomId = PlayFabSettings.DeviceUniqueIdentifier+"EDITOR"
}, RequestPhotonToken, OnPlayFabError);
}
/*
* Step 2
* We request a Photon authentication token from PlayFab.
* This is a crucial step, because Photon uses different authentication tokens
* than PlayFab. Thus, you cannot directly use PlayFab SessionTicket and
* you need to explicitly request a token. This API call requires you to
* pass a Photon App ID. The App ID may be hard coded, but in this example,
* we are accessing it using convenient static field on PhotonNetwork class.
* We pass in AuthenticateWithPhoton as a callback to be our next step, if
* we have acquired the token successfully.
*/
private void RequestPhotonToken(LoginResult obj) {
LogMessage("PlayFab authenticated. Requesting photon token...");
//We can player PlayFabId. This will come in handy during next step
_playFabPlayerIdCache = obj.PlayFabId;
PlayFabClientAPI.GetPhotonAuthenticationToken(new GetPhotonAuthenticationTokenRequest()
{
PhotonApplicationId = PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime
}, AuthenticateWithPhoton, OnPlayFabError);
}
/*
* Step 3
* This is the final and the simplest step. We create a new AuthenticationValues instance.
* This class describes how to authenticate a player inside the Photon environment.
*/
private void AuthenticateWithPhoton(GetPhotonAuthenticationTokenResult obj) {
LogMessage("Photon token acquired: " + obj.PhotonCustomAuthenticationToken + " Authentication complete.");
//We set AuthType to custom, meaning we bring our own, PlayFab authentication procedure.
var customAuth = new Photon.Realtime.AuthenticationValues { AuthType = CustomAuthenticationType.Custom };
//We add "username" parameter. Do not let it confuse you: PlayFab is expecting this parameter to contain player PlayFab ID (!) and not username.
customAuth.AddAuthParameter("username", _playFabPlayerIdCache); // expected by PlayFab custom auth service
//We add "token" parameter. PlayFab expects it to contain Photon Authentication Token issues to your during previous step.
customAuth.AddAuthParameter("token", obj.PhotonCustomAuthenticationToken);
//We finally tell Photon to use this authentication parameters throughout the entire application.
PhotonNetwork.AuthValues = customAuth;
}
private void OnPlayFabError(PlayFabError obj) {
LogMessage(obj.ErrorMessage);
}
public void LogMessage(string message) {
Debug.Log("PlayFab + Photon Example: " + message);
}
// Add small button to launch our example code
public void OnGUI() {
if (GUILayout.Button("Execute Example ")) ExecuteExample();
}
// Example code which raises custom room event, then sets custom room property
private void ExecuteExample() {
// Raise custom room event
var data = new Dictionary<string, object>() { {"Hello","World"} };
var result = PhotonNetwork.RaiseEvent(15, data, true, new RaiseEventOptions()
{
ForwardToWebhook = true,
});
LogMessage("New Room Event Post: "+result);
// Set custom room property
var properties = new ExitGames.Client.Photon.Hashtable() { { "CustomProperty", "It's Value" } };
var expectedProperties = new ExitGames.Client.Photon.Hashtable();
PhotonNetwork.room.SetCustomProperties(properties, expectedProperties, true);
LogMessage("New Room Properties Set");
}
}
- 运行中心场景并等待 PlayFab 身份验证完成 (1)。
- 然后加载 Boxes Demo 场景 (2)。
- 场景加载后,等待对等机连接新创建的房间 (1)。
- 然后选择左上角的 Execute Example(2)。
- 观察控制台输出 (3)。
- 确保未发生错误。
请勿忘记阻止 Unity 播放。 这样做是为了确保也收到 RoomLeft 和 RoomClosed 事件。
导航到游戏的 Game Manager 页面,然后观察 PlayStream 面板。 应能够查看由于 CloudScript 代码处理 Photon 事件而生成的事件。
- 最初 Photon 实例没有打开的房间。 启动示例后,Photon 为 Boxes Demo 创建了房间。
- 要加入的第一个玩家是请求房间的玩家。 因此不记录 RoomJoined 事件。 然后执行我们的示例代码:
- 首先,引发自定义房间事件。
- 然后,设置自定义房间属性。
- 然后停止 Unity 播放模式。 这会导致我们的客户端离开空间。
- 因为我们的断开连接客户端是最后一个,没有任何更多客户端,Photon 会关闭房间。
所有事件都应记录到 PlayStream 事件流中,如下图所示。
此时已将 Photon 事件支持完全集成到 PlayFab 游戏中。