游戏内邮箱
游戏内邮箱允许游戏开发者与玩家沟通。您可以使用它们来告知玩家游戏内活动、赠送有用的资源或帮助他们继续玩您的游戏。
先决条件
要使用此示例使用案例,您必须下载并安装 UGS 使用案例项目到您的 Unity 项目中。
概述
当玩家第一次加载场景时,他们会看到一个收件箱,其中列出了等待他们阅读的消息。在后续加载中,收件箱要么处于他们离开时的状态,要么由于会话之间消息过期而处于更新状态。
玩家可以与消息进行交互,领取附件、删除消息或将收件箱重置为全新的状态。
要查看此使用案例的实际操作
- 在 Unity 编辑器项目窗口中,选择**Assets** > **Use Case Samples** > **In-Game Mailbox**,然后双击
InGameMailboxSample.unity
打开示例场景。 - 进入播放模式与使用案例进行交互。
初始化
当场景加载时,InGameMailboxSceneManager
脚本执行以下初始化步骤
初始化 Unity 游戏服务。
使用身份验证服务匿名登录玩家。如果您之前已初始化任何其他示例场景,身份验证将使用您的缓存玩家 ID,而不是创建新的玩家 ID。
刷新经济配置数据。如果自玩家上次打开应用程序以来创建了新的经济物品,这将初始化玩家配置中的这些物品。
从经济服务检索并更新该已验证用户的货币余额。
使用存储在经济物品配置的自定义数据中的精灵地址,从 Addressables 加载所有可能的货币和库存物品精灵。
检索玩家收件箱的更新消息信息
- 从远程配置下载所有可能消息的列表。
- 从云保存检索玩家当前的收件箱数据。
- 检查玩家收件箱中已保存的任何消息是否已过期,如果是,则删除这些消息。
- 检查从远程配置下载但尚未添加到玩家收件箱的任何新消息。
- 将更新的收件箱状态保存到玩家的云保存中。
在场景中显示更新的收件箱消息列表。
功能
场景中的左侧面板显示玩家收件箱中的消息列表。此列表会随着时间的推移而更新,因为消息会过期,或根据玩家的交互而更新。
在列表下方,一个计数器显示收件箱中有多少条消息以及在任何给定时间收件箱中可以容纳的最大消息数。当玩家第一次加载场景时,收件箱已满。
当所有消息都从收件箱中删除时(通过玩家交互或消息过期),会出现一个弹出窗口,提示玩家重置收件箱。
Note: This pop-up is a usability feature of the sample, and would not be an expected interaction in a real-world implementation.
打开消息
当您从列表中选择一条消息时,将发生以下情况
- 消息的完整详细信息将显示在场景的右侧。
- 消息将标记为已读,并将该状态保存到云保存中。
如果消息有附件,则还会显示哪些经济物品附加以及一个领取它们的按钮。
领取附件
当您按下**领取**按钮时,客户端代码将调用Messages_ClaimAttachment.js
云代码脚本,并将所选消息的 ID 作为参数包含在内。以下情况发生在后端
- 客户端请求云保存收件箱数据,并定位具有所提供 ID 的消息。
- 该脚本检查消息是否具有未领取的附件。
- 假设消息确实具有未领取的附件,该脚本将使用
message.messageInfo.attachment
字段中的虚拟购买 ID 进行经济makeVirtualPurchase
调用。 - 如果购买过程成功,
message.metadata.hasUnclaimedAttachment
字段将设置为false
并保存在云保存中,因此玩家无法再次领取附件。
领取所有附件
当您按下**领取全部**按钮时,客户端代码将调用Messages_ClaimAllAttachments.js
云代码脚本。以下情况发生在后端
客户端从云保存请求收件箱数据。
云保存返回收件箱消息列表,该列表已过滤,仅显示
message.metadata.hasUnclaimedAttachment
设置为true
的消息。对于此过滤列表中的每条消息
- 该脚本使用
message.messageInfo.attachment
字段中的虚拟购买 ID 进行经济makeVirtualPurchase
调用。 - 如果购买过程成功,
message.metadata.hasUnclaimedAttachment
将设置为false
,并且message.metadata.isRead
将设置为true
。
- 该脚本使用
一旦所有消息附件都已领取,更新的消息列表将保存在云保存中。
Note: Saving changes in Cloud Save after each attachment is claimed would make the process more fault tolerant. However, it would also require more server calls and therefore be less efficient than the selected approach. It is up to the developer which advantage to prioritize.
删除消息
当您按下消息的**删除**按钮时
- 该消息将从本地收件箱消息列表中删除。
- 如果收件箱以前已满,因此删除消息为新消息腾出了空间,客户端将重新检查从远程配置下载的所有可能消息与云保存中保存的最后一条消息的 ID,以查看是否有要添加到收件箱的新消息。如果有,它将尽可能多地将这些消息添加到收件箱中。
- 然后将更新的收件箱消息列表保存在云保存中。
- 最后,视图刷新以显示更新的列表。如果删除的消息以前被选中,这也将更新 UI 以不显示删除的消息的详细信息视图。
删除所有已读并已领取的附件
当您按下**删除已读**按钮时
- 该脚本将循环遍历收件箱消息列表,并删除每条
message.metadata.isRead
设置为true
且message.metadata.hasUnclaimedAttachment
设置为false
的消息。此实现不会删除带有未领取附件的消息,以防止玩家意外删除带有可用附件的消息。 - 如果收件箱以前已满,因此删除消息为新消息腾出了空间,客户端将重新检查从远程配置下载的所有可能消息与云保存中保存的最后一条消息的 ID,以查看是否有要添加到收件箱的新消息。如果有,它将尽可能多地将这些消息添加到收件箱中。
- 然后将更新的收件箱消息列表保存在云保存中。
- 最后,视图刷新以显示更新的列表。如果删除的消息以前被选中,这也将更新 UI 以不显示删除的消息的详细信息视图。
为特定受众重置收件箱
在场景底部,您可以在模拟特定受众的同时重置收件箱
- 默认
- 所有支出者
- 未参与的玩家
- 法语使用者
- 新玩家
每个非默认受众都会向消息列表添加一条特定于该受众的消息。这些消息由游戏覆盖确定。
当您为给定受众重置收件箱时,将发生以下情况
- 场景将重置,清除所选消息字段并删除云保存收件箱数据。
- 客户端使用指定的受众查询远程配置,以检索包含先前省略的任何受众特定消息的潜在消息列表。
- 从远程配置数据中将最大数量的消息添加到收件箱,并保存在云保存中。
- 视图刷新以显示新消息列表。
打开玩家库存
当您按下库存包图标时,将发生以下情况
- 客户端调用
EconomyService.Instance.PlayerInventory.GetInventoryAsync()
以刷新玩家拥有的经济库存物品列表。 - 一个弹出窗口将显示生成的库存物品列表。
设置
要求
要复制此使用案例,您需要在项目中使用以下Unity 包
包 | 角色 |
---|---|
Addressables | 允许开发者使用资产地址检索资产。在此示例中,该服务根据存储在经济物品的自定义数据中的信息查找经济物品精灵。 |
身份验证 | 自动以匿名身份登录用户,以便在服务器端跟踪其数据。 |
云代码 | 在服务器端存储重要的验证逻辑。在这个用例中,它用于验证消息附件是否已被领取,并处理存储附件奖励的虚拟购买。 |
云保存 | 存储玩家的收件箱状态,包括从远程配置下载的消息信息,以及玩家特定的消息元数据,例如消息是否已读。 |
部署 | 提供一个连贯的界面来部署云服务的资产。 |
经济 | 维护玩家的钱包和库存,以及与特定消息附件相关的虚拟购买信息。 |
游戏覆盖 | 为只想发送给特定受众的消息定义受众分组和消息数据。 |
远程配置 | 提供键值对,其中映射到给定键的值可以在服务器端更改,无论是手动更改还是基于特定游戏覆盖更改。在这个示例中,我们在远程配置中存储消息信息。应该只发送给特定受众的消息存储为空白消息,并由游戏覆盖完成。 |
注意:虽然它被列为一个包,并且需要单独的仪表盘配置,但游戏覆盖实际上没有来自包管理器的 SDK 可供安装。它是一个服务器端产品,会影响从其他服务返回的值。
要在您的游戏中使用这些服务,请在 Unity Cloud 仪表盘 中为您的组织和项目激活每个服务。
Unity Cloud 服务配置
要在您自己的 Unity 项目中复制此示例场景的设置,请配置以下项目
- 云代码脚本
- 经济项目
- 远程配置值
- 远程配置游戏覆盖
要配置这些项目,您可以 使用部署包,或 使用 Unity Cloud 仪表盘手动输入它们。推荐的最佳实践是使用部署包,因为它可以大大加快此过程。
使用部署包
要使用部署包部署配置,请执行以下操作
- 打开 部署窗口。
- 选中
Common
和In-Game Mailbox
。 - 单击
Deploy Selection
。
这将部署以下项目
- 云代码脚本
- 经济项目
- 远程配置值
部署包不支持以下项目
- 远程配置游戏覆盖
要配置它们,请参考 使用 Unity Cloud 仪表盘。
使用 Unity Cloud 仪表盘
您可以使用 Unity Cloud 仪表盘 按项目和环境手动配置您的服务。请参考以下部分配置此示例。
云代码
脚本 | 参数 | 描述 | 项目中的位置 |
---|---|---|---|
Messages_ClaimAttachment | messageId 拥有玩家想要领取的附件的消息的 ID。 | 获取给定消息的适当附件,验证附件是否已被领取,调用 Economy 的处理购买方法以进行该虚拟购买,并将附件标记为已领取。 | Assets/Use Case Samples/In-Game Mailbox/Cloud Code/Messages_ClaimAttachment.js |
Messages_ClaimAllAttachments | 无 | 获取玩家收件箱中的消息列表,找到所有具有未领取附件的消息,并为每个虚拟购买调用 Economy 的处理购买方法,并将每条消息标记为已读,并将附件标记为已领取。 | Assets/Use Case Samples/In-Game Mailbox/Cloud Code/Messages_ClaimAllAttachments.js |
Note: The Cloud Code scripts included in the Cloud Code folder are local copies because you cannot view the sample project's dashboard. Changes to these scripts do not affect the behavior of this sample because they are not automatically uploaded to the Cloud Code service.
经济
资源类型 | 资源项目 | ID | 自定义数据 | 描述 |
---|---|---|---|---|
货币 | 宝石 | GEM |
| 一些消息赠送的优质货币。 |
货币 | 金币 | COIN |
| 一些消息赠送的软货币。 |
库存物品 | 剑 | SWORD |
| 一些消息赠送的库存物品。 |
库存物品 | 盾牌 | SHIELD |
| 一些消息赠送的库存物品。 |
此外,配置以下虚拟购买
项目名称 | ID | 此购买奖励 | 此购买费用 |
---|---|---|---|
消息 003 新玩家礼包 | MESSAGE_003_GIFT_NEW_PLAYERS | 剑 (1),盾牌 (1),金币 (100) | 无 * |
消息 004 非活跃玩家礼包 | MESSAGE_004_GIFT_UNENGAGED | 宝石 (50) | 无 * |
消息 005 礼包 | MESSAGE_005_GIFT | 金币 (50) | 无 * |
消息 008 礼包 | MESSAGE_008_GIFT | 金币 (100),宝石 (50) | 无 * |
消息 010 礼包 | MESSAGE_010_GIFT | 宝石 (50) | 无 * |
消息 011 礼包 | MESSAGE_011_GIFT | 剑 (1) | 无 * |
* There is no cost associated with these Virtual Purchases because they are all gifts to the player reading the message.
远程配置
键 | 类型 | 描述 | 值 |
---|---|---|---|
MESSAGES_ALL | JSON | Unity Cloud 仪表盘中所有可能的消息 ID 的 JSON 列表,按它们应该下载的顺序排列。 |
|
MESSAGE_001 | JSON | 玩家可能收到的消息之一。 |
|
MESSAGE_002 | JSON | 玩家可能收到的消息之一。 |
|
MESSAGE_003 | JSON | 玩家可能收到的消息之一。 |
|
MESSAGE_004 | JSON | 玩家可能收到的消息之一。 |
|
MESSAGE_005 | JSON | 玩家可能收到的消息之一。 |
|
MESSAGE_006 | JSON | 玩家可能收到的消息之一。 |
|
MESSAGE_007 | JSON | 玩家可能收到的消息之一。 |
|
MESSAGE_008 | JSON | 玩家可能收到的消息之一。 |
|
MESSAGE_009 | JSON | 玩家可能收到的消息之一。 |
|
MESSAGE_010 | JSON | 玩家可能收到的消息之一。 |
|
MESSAGE_011 | JSON | 玩家可能收到的消息之一。 |
|
游戏覆盖
详细信息 | 将覆盖命名为“所有支出者消息覆盖”。 |
目标 | 选择使用以下 JEXL 代码的 JEXL *
|
内容 | 选择 选择内容类型 > 配置覆盖,然后为以下键输入覆盖值 键
值
|
调度 | 设置以下开始和结束日期
|
状态 | 完成创建游戏覆盖后,单击 启用。 |
详细信息 | 将覆盖命名为“法语使用者消息覆盖”。 |
目标 | 选择使用以下 JEXL 代码的 JEXL *
|
内容 | 选择 选择内容类型 > 配置覆盖,然后为以下键输入覆盖值 键
值
|
调度 | 设置以下开始和结束日期
|
状态 | 完成创建游戏覆盖后,单击 启用。 |
详细信息 | 将覆盖命名为“新玩家消息覆盖”。 |
目标 | 选择使用以下 JEXL 代码的 JEXL *
|
内容 | 选择 选择内容类型 > 配置覆盖,然后为以下键输入覆盖值 键
值
|
调度 | 设置以下开始和结束日期
|
状态 | 完成创建游戏覆盖后,单击 启用。 |
详细信息 | 将覆盖命名为“非活跃玩家消息覆盖”。 |
目标 | 选择使用以下 JEXL 代码的 JEXL *
|
内容 | 选择 选择内容类型 > 配置覆盖,然后为以下键输入覆盖值 键
值
|
调度 | 设置以下开始和结束日期
|
状态 | 完成创建游戏覆盖后,单击 启用。 |
* This sample determines which Game Override data to return based on a JEXL match with the audience value specified in the client. This allows the sample to simulate a player being in different audiences on-demand. In a real app, the Game Overrides would likely be set up to use built-in or custom-defined Analytics audiences for targeting. For example, during the Game Override targeting step, you could choose Stateful (Audiences) and check the appropriate Analytics audience from the list or click Build a new Audience.