# 시작하기

> Follow this workflow to set up Triggers and automate rewarding top players from Leaderboards.

이 섹션에서는 Triggers를 시작하는 데 필요한 모든 단계를 설명합니다.

아래 샘플은 Triggers를 사용하여 [리더보드](/leaderboards.md)의 상위 플레이어 5명에게 Scheduler에 의해 발생되는 일회성 일정 이벤트를 통해 [Cloud Save](/cloud-save.md)에서 시즌 트로피를 수여하는 방법을 보여 줍니다.

## 동영상 가이드##video-walkthrough

Unity Dashboard에서 트리거를 생성하는 단계를 자세히 알아보려면 아래의 동영상을 참고하십시오.


[Video content](https://youtu.be/eTnxB3OczOY)

## 일반적인 워크플로##typical-workflow

다음 단계를 따라 Triggers를 시작합니다.

1. [이벤트에서 실행할 Cloud Code 스크립트 또는 모듈 생성:](#set-up-cloud-code) 이벤트가 발생할 때 실행할 게임 로직을 정의합니다.
2. [리소스 상태를 변경하는 이벤트 일정 예약:](#schedule-an-event) 이벤트가 발생할 시점을 정의합니다.
3. [이벤트에서 Cloud Code 모듈 엔드포인트를 실행할 트리거 구성:](#configure-a-trigger) 이벤트가 발생할 때 실행할 Cloud Code 스크립트 또는 모듈을 정의합니다.
4. [결과 확인:](#validate-the-result) Cloud Code 스크립트 또는 모듈이 실행되었는지 확인합니다.

> **Note:**
>
> **참고**: Triggers에서 다른 서비스에서 발생된 이벤트를 사용할 수도 있습니다. 자세한 내용은 [이벤트](./manage-events/events.md) 섹션을 참고하십시오.

## 필수 조건##prerequisites

이 단계는 [Unity Dashboard의 Unity Gaming Services 프로젝트](/cloud/projects/create-project.md)를 이미 생성했다고 가정합니다.

먼저 필요한 액세스 역할로 서비스 계정을 생성하고 [UGS CLI](https://services.docs.unity.com/guides/ugs-cli/latest/general/get-started/install-the-cli/)를 구성해야 합니다.

### 서비스 계정을 사용하여 인증##authenticate-using-a-service-account

Scheduling 및 Triggers 서비스를 호출하려면 먼저 서비스 계정을 사용하여 인증해야 합니다.

1. [Unity Dashboard](https://cloud.unity.com)로 이동합니다.
2. **Administration** > **Service Accounts**를 선택합니다.
3. **New** 버튼을 선택하고 서비스 계정의 이름과 설명을 입력합니다.
4. **Create**를 선택합니다.

다음과 같이 제품 역할을 추가하고 키를 만듭니다.

1. **Manage product roles**를 선택합니다.
2. 다음 역할을 서비스 계정에 추가합니다.
   * LiveOps 드롭다운에서 **Triggers Configuration Editor**, **Triggers Configuration Viewer**, **Scheduler Configuration Editor**, **Scheduler Configuration Viewer**, **Leaderboards Admin**을 선택합니다.
   * Admin 드롭다운에서 **Unity Environments Viewer**를 선택합니다.
3. **Save**를 선택합니다.
4. **Add Key**를 선택합니다.
5. base64 인코딩을 사용하여 **Key ID**와 **Secret key**를 인코딩합니다. 포맷은 ‘key\_id:secret\_key’입니다. 이 값을 기록해 둡니다.

자세한 내용은 [인증](/triggers/authentication.md)을 참고하십시오.

### UGS CLI 구성##configure-the-ugs-cli

다음 단계를 따라 UGS CLI를 시작합니다.

1. [UGS CLI를 설치합니다](https://services.docs.unity.com/guides/ugs-cli/latest/general/get-started/install-the-cli/).

2. 다음과 같이 프로젝트 ID와 환경을 구성합니다.
   `ugs config set project-id <your-project-id>`
   `ugs config set environment-name <your-environment-name>`

3. 이전에 생성한 서비스 계정을 사용하여 인증합니다. [인증 받기](https://services.docs.unity.com/guides/ugs-cli/latest/general/get-started/get-authenticated/)를 참고하십시오.

### Leaderboards 설정##set-up-leaderboards

이 샘플을 따르려면 리더보드를 생성해야 합니다.

UGS CLI를 사용하여 다음 `leaderboard.lb` 파일을 배포할 수 있습니다. 이는 오름차순으로 리더보드를 정의하며 최고 점수를 계속 표시합니다.

`new-file` 커맨드를 실행하여 로컬에서 리더보드 구성을 생성합니다.

```bash
ugs leaderboards new-file leaderboard
```

파일 이름은 리더보드 ID와 상응합니다. 다음 구성을 사용하여 `leaderboard.lb` 파일을 업데이트합니다.

```json
{
  "$schema": "https://ugs-config-schemas.unity3d.com/v1/leaderboards.schema.json",
  "SortOrder": "asc",
  "UpdateType": "keepBest",
  "Name": "leaderboard"
}
```

다음과 같이 UGS CLI 툴을 사용하여 파일을 배포합니다.

```bash
ugs deploy leaderboard.lb
```

리더보드를 생성했으므로 이제 점수를 추가할 수 있습니다.

### 선택 사항: 리더보드에 점수 추가##optional:-add-scores-to-the-leaderboard

다음 Cloud Code 스크립트를 실행하여 점수를 [Unity Dashboard](https://cloud.unity.com)의 리더보드에 추가할 수 있습니다. 새 플레이어의 점수를 생성하려면 모든 테스트 실행에서 플레이어 ID 토큰을 재생성해야 합니다.

#### JavaScript##javascript

```javascript
const { LeaderboardsApi } = require("@unity-services/leaderboards-1.1");
const _ = require("lodash-4.17");

module.exports = async ({ params, context, logger }) => {

  const leaderboardsApi = new LeaderboardsApi({ accessToken: context.accessToken });
  const leaderboardID = "leaderboard";

  var randomScore = _.random(1, 100);
  try {
    await leaderboardsApi.addLeaderboardPlayerScore(context.projectId, leaderboardID, context.playerId, { score: randomScore });

  } catch (err) {
    logger.error("Failed to add score to the leaderboard", { "error.message": err.message });
  }
};
```

## Cloud Code 설정##set-up-cloud-code

Triggers 서비스를 사용하려면 Cloud Code 모듈이나 Cloud Code 스크립트를 정의해야 합니다. 트리거가 발동하면 모듈이나 스크립트가 실행됩니다. 아래 샘플에서는 [Leaderboards](/leaderboards.md)와 [Cloud Save](/cloud-save.md)를 Cloud Code와 연동하여 리더보드의 상위 플레이어 5명에게 시즌 트로피를 수여합니다.

### Cloud Code C# 모듈##cloud-code-c-module

문자열 인자 `key`와 `value`가 있는 함수를 사용하여 `SchedulerHelloWorld` 모듈을 정의합니다.

모듈 엔드포인트 `RewardPlayers`는 리더보드의 상위 플레이어 5명을 가져와 지정된 키와 값으로 각 플레이어의 Cloud Save 데이터를 설정합니다.

```csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Unity.Services.CloudCode.Apis;
using Unity.Services.CloudCode.Core;
using Unity.Services.CloudCode.Shared;
using Unity.Services.CloudSave.Model;
using Unity.Services.Leaderboards.Model;

namespace SchedulerHelloWorld;

public class SchedulerHelloWorld
{
    private const string LeaderboardId = "leaderboard";
    private readonly ILogger<SchedulerHelloWorld> _logger;
    public SchedulerHelloWorld(ILogger<SchedulerHelloWorld> logger)
    {
        _logger = logger;
    }

    [CloudCodeFunction("RewardPlayers")]
    public async Task RewardPlayers(IExecutionContext ctx, IGameApiClient gameApiClient, string key, string value)
    {
        var top5Players = await GetTop5(ctx, gameApiClient);
        foreach (var score in top5Players)
        {
            try
            {
                var response = await gameApiClient.CloudSaveData.SetItemAsync(ctx, ctx.ServiceToken, ctx.ProjectId, score.PlayerId, new SetItemBody(key, value));
                _logger.LogInformation("Data saved successfully");
            }
            catch (ApiException e)
            {
                _logger.LogError( "Failed to record data for playerId {playerId}. Error: {Error}", score.PlayerId, e.Message);
                throw new Exception($"Failed to record data for playerId {score.PlayerId}. Error: {e.Message}");
            }
        }
    }

    [CloudCodeFunction("GetTopPlayers")]
    public async Task<List<LeaderboardEntry>> GetTop5(IExecutionContext ctx, IGameApiClient gameApiClient)
    {
        try
        {
            var results = await gameApiClient.Leaderboards.GetLeaderboardScoresAsync(ctx, ctx.ServiceToken, new Guid(ctx.ProjectId),
                LeaderboardId, null, 5);
            return results.Data.Results;

        }
        catch (ApiException e)
        {
            _logger.LogError(e, "Failed to get top players for leaderboard: {LeaderboardId}. Error: {Error}", LeaderboardId, e.Message);
            throw new Exception($"Failed to get top players for leaderboard: {LeaderboardId}. Error: {e.Message}");
        }
    }

    public class ModuleConfig : ICloudCodeSetup
    {
        public void Setup(ICloudCodeConfig config)
        {
            config.Dependencies.AddSingleton(GameApiClient.Create());
        }
    }

}
```

모듈을 배포합니다.

모듈을 배포하는 방법을 알아보려면 [Hello World 배포](/cloud-code/modules/getting-started.md#deploy-the-module)를 참고하십시오.

> **Note:**
>
> **참고:** UGS CLI를 사용하여 모듈을 배포하는 경우 서비스 계정 역할 `Cloud Code Editor`를 추가해야 합니다.

### Cloud Code JavaScript 스크립트##cloud-code-javascript-script

Cloud Code 스크립트를 생성해서도 똑같은 결과물을 얻을 수 있습니다.

다음과 같이 필수 문자열 인자인 `key`와 `value`를 사용하여 `SchedulerHelloWorld` 스크립트를 생성합니다.

#### JavaScript##javascript

```javascript
const { DataApi } = require("@unity-services/cloud-save-1.4");
const { LeaderboardsApi } = require("@unity-services/leaderboards-1.1");


module.exports = async ({ params, context, logger }) => {
  // Get top 5 players from the Leaderboard
  const leaderboardId = "my-leaderboard";
  const leaderboardsApi = new LeaderboardsApi(context);
  const cloudSaveApi = new DataApi(context);

  let result;

  try {
    result = await leaderboardsApi.getLeaderboardScores(context.projectId, leaderboardId, 0, 5);
  } catch (err) {
    logger.error("Failed to retrieve players from the leaderboard", { "error.message": err.message });
    throw err;
  }

  // Set Cloud Save data for every player
  const promises = result.data.results.map(async (score) => {
    try {

      await cloudSaveApi.setItem(context.projectId, score.playerId, {
        key: params.key,
        value: params.value,
      });

    } catch (err) {
      logger.error("Failed to update Cloud Save data", { "error.message": err.message }, { "affectedPlayerId": score.playerId });
      return;
    }
  });

  await Promise.all(promises);
};
```

스크립트를 퍼블리시합니다.

스크립트를 배포하는 방법을 알아보려면 [Hello World 배포](/cloud-code/scripts/getting-started.md#deploying-hello-world)를 참고하십시오.

> **Note:**
>
> **참고:** UGS CLI를 사용하여 스크립트를 배포하는 경우 서비스 계정 역할 `Cloud Code Script Publisher`와 `Cloud Code Editor`를 추가해야 합니다.

## 이벤트 일정 예약##schedule-an-event

Cloud Code 스크립트 또는 모듈을 정의한 후 상위 플레이어 5명에게 트로피를 수여할 시점을 결정하는 일정을 생성할 수 있습니다.

아래 샘플은 플레이어에게 시즌 트로피를 부여하는 일회성 일정을 정의합니다.

`new-file` 커맨드를 실행하여 로컬에서 일정 구성을 생성합니다.

```bash
ugs scheduler new-file schedule-config
```

다음 구성을 사용하여 `schedule-config.sched` 파일을 업데이트합니다.

```json
{
  "$schema": "https://ugs-config-schemas.unity3d.com/v1/schedules.schema.json",
  "Configs": {
    "grant-trophy": {
      "EventName": "trophy-for-top-5",
      "Type": "one-time",
      "Schedule": "2024-08-28T00:00:00Z",
      "PayloadVersion": 1,
      "Payload": "{\"key\": \"seasonal-trophy\", \"value\": \"2024-08-28\"}"
    }
  }
}
```

이벤트의 `payload`는 Cloud Code 스크립트 또는 모듈에 전달되는 Cloud Code 파라미터를 포함합니다. 이벤트가 트리거되는 날짜와 시간을 변경하려면 `schedule` 필드를 수정합니다.

다음과 같이 UGS CLI 툴을 사용하여 구성을 배포합니다.

```bash
ugs deploy schedule-config.sched
```

다음과 유사한 응답이 표시됩니다.

```text
Deployed:
    schedule-config.sched
```

이제 특정 시간에 이벤트를 트리거하는 일정이 만들어졌습니다. 하지만 이벤트가 아직 Cloud Code 스크립트 또는 모듈에 연결되지 않았습니다.

## 트리거 구성##configure-a-trigger

Cloud Code 리소스를 일정에 연결하려면 트리거를 생성합니다. 일정이 트리거되는 등 이벤트가 발생하면 트리거가 Cloud Code 모듈 또는 스크립트를 실행합니다.

`new-file` 커맨드를 실행하여 로컬에서 트리거 구성을 생성할 수 있습니다.

```bash
ugs triggers new-file triggers-config
```

Cloud Code 모듈을 생성한 경우, 다음 구성으로 `triggers-config.tr` 파일을 업데이트합니다.

```json
{
  "$schema": "https://ugs-config-schemas.unity3d.com/v1/triggers.schema.json",
  "Configs": [
    {
      "Name": "trophy-reward",
      "EventType": "com.unity.services.scheduler.trophy-for-top-5.v1",
      "ActionUrn": "urn:ugs:cloud-code:SchedulerHelloWorld/RewardPlayers",
      "ActionType": "cloud-code"
    }
  ]
}
```

Cloud Code 스크립트를 생성한 경우, 다음 구성으로 `triggers-config.tr` 파일을 업데이트합니다.

```json
{
  "$schema": "https://ugs-config-schemas.unity3d.com/v1/triggers.schema.json",
  "Configs": [
    {
      "Name": "trophy-reward",
      "EventType": "com.unity.services.scheduler.trophy-for-top-5.v1",
      "ActionUrn": "urn:ugs:cloud-code:SchedulerHelloWorld",
      "ActionType": "cloud-code"
    }
  ]
}
```

다음과 같이 UGS CLI 툴을 사용하여 구성을 배포합니다.

```bash
ugs deploy triggers-config.tr
```

다음과 유사한 응답이 표시됩니다.

```text
Deployed:
    triggers-config.tr
```

이제 이벤트가 발생할 때 Cloud Code 스크립트 또는 모듈을 실행하는 트리거를 만들었습니다.

## 결과 확인##validate-the-result

결과를 확인하려면 이벤트 발생 전후의 상위 플레이어를 검사하면 됩니다.

1. [Unity Dashboard](https://cloud.unity.com)로 이동합니다.
2. **Products** > **Leaderboards**를 선택합니다.
3. **Overview** 섹션을 선택합니다.
4. `leaderboard` 리더보드를 선택합니다.
5. **Entries** 탭을 선택합니다.
6. 상위 플레이어 ID 중 하나를 기록해 둡니다.

다음과 같이 플레이어의 Cloud Save 데이터를 확인하면 플레이어 데이터가 업데이트되었는지 검증할 수 있습니다.

1. [Unity Dashboard](https://cloud.unity.com)에서 **Products** > **Player Management**를 선택합니다.
2. 검색 필드에 앞서 기록해 둔 플레이어 ID를 입력하고 **Find Player**를 선택합니다.
3. **Cloud Save** > **Data** 섹션으로 이동합니다.
4. `seasonal-trophy` 키와 함께 `2023-08-28` 값을 확인할 수 있습니다.

Cloud Code 로그에서도 Cloud Code 스크립트나 모듈이 실행되었는지 확인할 수 있습니다.

1. [Unity Dashboard](https://cloud.unity.com)에서 **Cloud Code**를 엽니다.
2. **Logs**를 선택합니다.

**Logs** 페이지에 `SchedulerHelloWorld` 모듈이나 스크립트의 로그 엔트리가 표시됩니다.
