季节性活动

季节性活动可以增加游戏场次和玩家对游戏的总体兴趣,因为它们可以让现有玩家在一年四季都能期待新的有趣内容,并可以吸引新玩家开始游戏。本示例展示了如何设置季节性活动。它展示了四个活动:秋季、冬季、春季和夏季,但是您可以扩展此示例以配置您想要的任何活动的事件。每个活动都会显示您在活动期间可以赢得的货币奖励,一个指示当前活动剩余时间的倒计时,以及一个“开始挑战”按钮,该按钮会打开一个弹出窗口,玩家可以在其中收集赢得挑战的奖励。

先决条件

要使用此示例用例,您必须下载并安装 Unity 项目中的 UGS 用例项目。

概览

要查看此用例的实际应用,请打开示例菜单并导航到“季节性活动”。要直接打开此场景并与用例交互

  1. 在 Unity 编辑器的“项目”窗口中,选择“资源”>“用例示例”>“季节性活动”,然后双击“SeasonalEventsSample.unity”以打开示例场景。
  2. 按“播放”进入播放模式。

初始化

“SeasonalEventsSceneManager.cs”脚本在其“Start”函数中执行以下初始化任务

  1. 初始化 Unity Gaming Services。
  2. 使用身份验证服务匿名登录玩家。如果您之前初始化过任何其他示例场景,则身份验证将使用您缓存的玩家 ID,而不是创建新的 ID。
  3. 从经济服务中检索并更新玩家的货币余额。
  4. 调用“GetServerTime”云代码函数,以便根据服务器时间设置游戏覆盖和远程配置数据。
  5. 查询远程配置服务以获取与活动相关的键的当前值(请参阅以下有关活动参数的部分)。

活动参数

远程配置服务存储用于显示活动活动名称、完成活动挑战的潜在奖励的键值数据。这些键还用于从 Addressables 服务中检索活动的主题界面视觉效果。

远程配置还传达活动何时结束,"CountdownManager.cs"脚本会参考该时间来确定当前活动剩余多少时间。当时间耗尽时,它会触发对远程配置的新调用,以获取下一个活动的更新值。

**注意**:本示例根据当前服务器时间中分钟数的最后一位数确定返回哪些游戏覆盖数据。为了能够频繁地观察季节变化,这是一个简化。在真实的应用程序中,开发者可能会将游戏覆盖设置为具有特定的开始和结束日期,然后远程配置会根据服务器的日期和时间确定何时显示游戏覆盖。在这种情况下,客户端和服务器的实现可能有所不同。

功能

收集奖励

“开始挑战”按钮是对玩家可能参与的游戏玩法的抽象,以获得活动奖励。点击它会打开一个弹出窗口,玩家可以在其中收集“赢得”挑战的奖励。当您点击“收集奖励”按钮时,会发生以下情况

  1. 该按钮的“OnClick”方法调用“SeasonalEvents_GrantEventReward.js”云代码脚本,该脚本查询远程配置服务以确定要分发的奖励。

    **注意**:如果玩家正在更改其设备时钟,或者他们在活动即将结束时发起了索赔,则奖励可能与玩家的预期不同。

  2. 然后,云代码调用经济服务来授予相应的奖励并更新玩家的货币和库存余额。

  3. 奖励分发后,调用脚本会更新货币 HUD 并关闭收集奖励弹出窗口。

每个活动您只能玩一次挑战,因此在云代码脚本分发奖励后,它会将当前活动名称和时间戳保存到云存档。客户端使用此信息来确定当前活动是否已经玩过,如果玩过,则禁用“开始挑战”按钮。

设置

要求

要复制此用例,您需要在项目中包含以下Unity 软件包

软件包作用
可寻址资产系统允许按地址检索资源。无论资源位于何处(本地或远程),系统都会找到它及其依赖项,然后将其返回。在本示例中,它根据远程配置中的信息检索特定于活动的图像和预制件。
身份验证自动匿名登录用户,以便在服务器端跟踪其数据。
云代码在服务器端包含重要的验证逻辑。在本示例中,它分发活动挑战的奖励。它还在服务器端独立验证奖励分发时的时间戳,以确认要分发哪些活动奖励。
云存档存储一个标志,指示当前挑战是否已经玩过,以防止玩家多次参与。
部署提供一个统一的界面来部署云服务的资源。
经济在运行时检索玩家的起始和更新后的货币余额。
游戏覆盖维护四个季节性活动,并根据认为哪个游戏覆盖处于活动状态返回某些键的不同值。
远程配置提供可以在服务器端更改的键值对,可以手动更改,也可以根据特定的游戏覆盖进行更改。

**注意**:尽管游戏覆盖被列为一个软件包,并且需要单独的控制面板配置,但它实际上没有可从 Package Manager 安装的 SDK。它是一种服务器端产品,会影响从其他服务返回的值。

要在您的游戏中使用这些服务,请在Unity 云控制面板中为您的组织和项目激活每个服务。

Unity 云服务配置

要在您自己的 Unity 项目中复制此示例场景的设置,请配置以下项目

  • 云代码脚本
  • 经济项目
  • 远程配置值
  • 远程配置游戏覆盖

要配置这些项目,您可以使用部署包,也可以使用 Unity 云控制面板手动输入。建议的最佳实践是使用部署包,因为它可以大大加快此过程。

使用部署包

要使用部署包部署配置,请执行以下操作

  1. 打开部署窗口
  2. 选中“通用”和“季节性活动”。
  3. 点击“部署选择”。

这将部署以下项目

  • 云代码脚本
  • 经济项目
  • 远程配置值

部署包不支持以下项目

  • 远程配置游戏覆盖

要配置它们,请参阅使用 Unity 云控制面板

使用 Unity 云控制面板

您可以使用Unity 云控制面板按项目和环境手动配置您的服务。请参阅以下部分以配置此示例。

云代码

在 Unity 云控制面板中发布以下脚本

脚本参数描述项目中的位置
SeasonalEvents_GrantEventReward验证并分发奖励。资源/用例示例/季节性活动/云代码/SeasonalEvents_GrantEventReward.js
SeasonalEvents_GetServerTime从服务器检索当前时间戳,以便根据服务器授权时间设置 UI。资源/用例示例/季节性活动/云代码/SeasonalEvents_GetServerTime.js

注意:由于您无法查看示例项目的控制面板,因此 Cloud Code 文件夹中包含的 Cloud Code 脚本是本地副本。 对这些脚本的更改不会影响此示例的行为,因为它们不会自动上传到 Cloud Code 服务。

经济

在 Unity 云控制台中配置以下资源

资源类型资源名称ID描述
货币硬币COIN秋季、冬季和春季活动的挑战奖励。
货币宝石GEM冬季和夏季活动的挑战奖励
货币珍珠PEARL秋季和夏季活动的挑战奖励
货币星星STAR春季和夏季活动的挑战奖励

远程配置

在 Unity 云控制台中设置以下配置值

类型描述
EVENT_NAME字符串要在场景中显示的事件名称。空默认值
EVENT_KEY字符串用于查找特定于事件的值的键,例如特定图像的地址。空默认值
EVENT_END_TIME整数与 Audience JEXL 语句匹配的最后一位数字,即返回此活动的最新时间戳的最后一位数字。0
CHALLENGE_REWARDJSON指定在挑战“获胜”时分发哪些奖励的 json。
{ 
  "rewards": [{ 
    "id": "COIN", 
    "quantity": 100, 
    "sprite_address": "Sprites/Currency/Coin" 
  }] 
}

游戏覆盖

在 Unity 云控制台中配置以下覆盖

详情将覆盖命名为“秋季活动”。
目标

选择带有以下 JEXL 代码的JEXL

user.timestampMinutes % 10 == 0 || user.timestampMinutes % 10 == 1 || user.timestampMinutes % 10 == 2
内容

选择选择内容类型 > 配置覆盖,然后输入以下键的覆盖值

  • EVENT_NAME: “秋季活动
  • EVENT_KEY: “秋季
  • EVENT_END_TIME: 2
  • CHALLENGE_REWARD:
    {
    	  "rewards":[
    	    {
    	      "id": "COIN",
    	      "quantity": 100,
    	      "spriteAddress": "Sprites/Currency/Coin"
    	    },
    	    {
    	      "id": "PEARL",
    	      "quantity": 50,
    	      "spriteAddress": "Sprites/Currency/Pearl"
    	    }
    	  ]
    	}
日程安排

设置以下开始和结束日期

  • 开始日期设置为立即更新内容
  • 结束日期设置为无限期运行
状态

完成游戏覆盖创建后,单击启用

详情将覆盖命名为“冬季活动”。
目标

选择带有以下 JEXL 代码的JEXL

user.timestampMinutes % 10 == 3 || user.timestampMinutes % 10 == 4
内容

选择选择内容类型 > 配置覆盖,然后输入以下键的覆盖值

  • EVENT_NAME: “冬季活动
  • EVENT_KEY: “冬季
  • EVENT_END_TIME: 4
  • CHALLENGE_REWARD:
    {
      "rewards":[
        {
          "id": "COIN",
          "quantity": 100,
          "spriteAddress": "Sprites/Currency/Coin"
        },
        {
          "id": "GEM",
          "quantity": 50,
          "spriteAddress": "Sprites/Currency/Gem"
        }
      ]
    }
日程安排

设置以下开始和结束日期

  • 开始日期设置为立即更新内容
  • 结束日期设置为无限期运行
状态

完成游戏覆盖创建后,单击启用

详情将覆盖命名为“春季活动”。
目标

选择带有以下 JEXL 代码的JEXL

user.timestampMinutes % 10 == 5 || user.timestampMinutes % 10 == 6 || user.timestampMinutes % 10 == 7
内容

选择选择内容类型 > 配置覆盖,然后输入以下键的覆盖值

  • EVENT_NAME: “春季活动
  • EVENT_KEY: “春季
  • EVENT_END_TIME: 7
  • CHALLENGE_REWARD:
    {
      "rewards":[
        {
    	  "id": "COIN",
    	  "quantity": 100,
    	  "spriteAddress": "Sprites/Currency/Coin"
    	},
    	{
    	  "id": "STAR",
    	  "quantity": 50,
    	  "spriteAddress": "Sprites/Currency/Star"
    	}
      ]
    }
日程安排

设置以下开始和结束日期

  • 开始日期设置为立即更新内容
  • 结束日期设置为无限期运行
状态

完成游戏覆盖创建后,单击启用

详情将覆盖命名为“夏季活动”。
目标

选择带有以下 JEXL 代码的JEXL

user.timestampMinutes % 10 == 8 || user.timestampMinutes % 10 == 9
内容

选择选择内容类型 > 配置覆盖,然后输入以下键的覆盖值

  • EVENT_NAME: “夏季活动
  • EVENT_KEY: “夏季
  • EVENT_END_TIME: 9
  • CHALLENGE_REWARD:
    {
      "rewards":[
        {
          "id": "STAR",
          "quantity": 50,
    	  "spriteAddress": "Sprites/Currency/Star"
    	},
    	{
    	  "id": "PEARL",
    	  "quantity": 50,
    	  "spriteAddress": "Sprites/Currency/Pearl"
    	},
    	{
    	  "id": "GEM",
    	  "quantity": 50,
    	  "spriteAddress": "Sprites/Currency/Gem"
    	}
      ]
    }
日程安排

设置以下开始和结束日期

  • 开始日期设置为立即更新内容
  • 结束日期设置为无限期运行
状态

完成游戏覆盖创建后,单击启用