사용 사례 샘플: 참여한 로비에 있는 모든 플레이어에게 레벨 업 알림
Announce a player's level up to all other players in joined lobbies through a push message.
읽는 시간 4분최근 업데이트: 12시간 전
이 사용 사례 샘플에서는 플레이어가 있는 모든 로비에서 Triggers를 사용하여 모든 다른 플레이어에게 플레이어의 레벨 업을 알리는 방법을 보여 줍니다. 샘플은 Cloud Save 서비스에서 발생하는
key-saved필수 조건
먼저 필요한 액세스 역할로 서비스 계정을 생성해야 합니다.서비스 계정을 사용하여 인증
Triggers 서비스를 호출하려면 먼저 서비스 계정을 사용하여 인증해야 합니다.- Unity Dashboard로 이동합니다.
- Administration > Service Accounts를 선택합니다.
- New 버튼을 선택하고 서비스 계정의 이름과 설명을 입력합니다.
- Create를 선택합니다.
- Manage product roles를 선택합니다.
- 다음 역할을 서비스 계정에 추가합니다.
- LiveOps 드롭다운에서 Triggers Configuration Editor와 Triggers Configuration Viewer를 선택합니다.
- Admin 드롭다운에서 Unity Environments Viewer를 선택합니다.
- LiveOps 드롭다운에서 Triggers Configuration Editor와 Triggers Configuration Viewer를 선택합니다.
- Save를 선택합니다.
- Add Key를 선택합니다.
- base64 인코딩을 사용하여 Key ID와 Secret key를 인코딩합니다. 포맷은 ‘key_id:secret_key’입니다. 이 값을 기록해 둡니다.
key-saved 이벤트 확인
Cloud Save 서비스는 Cloud Save 키가 저장될 때key-saved이벤트는 이벤트 페이로드를 파라미터로 Cloud Code에 전달합니다. 자세한 내용은 Cloud Save: 키 저장을 참고하십시오.{ "id": "7LpyhpsIvEczGkDI1r8J6gHhHezL", "idType": "player", "key": "LEVEL", "value": 1, "valueIncluded": true, "writeLock": "7b8920a57912509f6b5cbb183eb7fcb0", "accessClass": "default", "modifiedDate": "2021-03-04T09:00:00Z"}
Cloud Code 설정
플레이어가 레벨 업하면 로비에 있는 모든 플레이어에게 푸시 메시지를 전송하는 모듈 엔드포인트를 정의합니다. 아래와 같은 내용으로AnnounceLevelUp모듈을 배포합니다. 모듈을 배포하는 방법을 알아보려면 Hello World 배포를 참고하십시오.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.Lobby.Model;namespace AnnounceLevelUp;public class AnnounceLevelUp{ private const string ServiceId = "cloud-code"; private readonly ILogger<AnnounceLevelUp> _logger; public AnnounceLevelUp(ILogger<AnnounceLevelUp> logger) { _logger = logger; } [CloudCodeFunction("AnnounceLevelUp")] public async Task Announce(IExecutionContext ctx, PushClient pushClient, IGameApiClient gameApiClient, string id) { try { var playerList = await GetPlayersFromLobbies(ctx, gameApiClient, id); if (playerList.Count == 0) { _logger.LogInformation("The player {playerId} has not joined any lobbies", id); return; } await SendPushMessage(ctx, pushClient, playerList); } catch (ApiException e) { _logger.LogError("Failed to announce level up for player {playerId}. Error: {Error}", id, e.Message); throw new Exception($"Failed to announce level up for player {id}. Error: {e.Message}"); } } public async Task SendPushMessage(IExecutionContext ctx, PushClient pushClient, List<Player> lobbyPlayers) { foreach (var lobbyPlayer in lobbyPlayers) { try { var message = $"The player {lobbyPlayer.Id} has leveled up!"; _logger.LogInformation("Sending push notification to player {lobbyPlayer}", lobbyPlayer.Id); await pushClient.SendPlayerMessageAsync(ctx, message, "Level up!", lobbyPlayer.Id); } catch (ApiException e) { _logger.LogError("Failed to send push notification to player {playerId}. Error: {Error}", lobbyPlayer.Id, e.Message); } } } public async Task<List<Player>> GetPlayersFromLobbies(IExecutionContext ctx, IGameApiClient gameApiClient, string playerId) { var playersToNotify = new List<Player>(); try { var lobbyList = await gameApiClient.Lobby.GetJoinedLobbiesAsync(ctx, ctx.ServiceToken, ServiceId,playerId ); foreach (var lobby in lobbyList.Data) { var players = await GetLobbyData(ctx, gameApiClient, lobby); playersToNotify.AddRange(players); } return playersToNotify; } catch (Exception e) { _logger.LogError("Failed to get players from lobbies. Error: {Error}", e.Message); throw new Exception($"Failed to get players from lobbies. Error: {e.Message}"); } } public async Task<List<Player>> GetLobbyData(IExecutionContext ctx, IGameApiClient gameApiClient, string lobbyId) { try { var response = await gameApiClient.Lobby.GetLobbyAsync(ctx, ctx.ServiceToken, lobbyId, "cloud-code"); return response.Data.Players; } catch (Exception e) { _logger.LogError("Failed to get players from lobby: {lobbyId}. Error: {Error}", lobbyId, e.Message); throw new Exception($"Failed to get players from lobby: {lobbyId}. Error: {e.Message}"); } } public class ModuleConfig : ICloudCodeSetup { public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(GameApiClient.Create()); config.Dependencies.AddSingleton(PushClient.Create()); } }}
트리거 구성
Cloud Code 리소스를 Cloud Savekey-savedkey_id:secret_key플레이어가curl 'https://services.api.unity.com/triggers/v1/projects/<PROJECT_ID>/environments/<ENVIRONMENT_ID>/configs' \--header 'Content-Type: application/json' \--header 'Authorization: Basic <SERVICE_ACCOUNT_CREDENTIALS_ENCODED>' \--data '{ "name": "announce-level-up", "eventType": "com.unity.services.cloud-save.key-saved.v1", "actionType": "cloud-code", "actionUrn": "urn:ugs:cloud-code:AnnounceLevelUp/AnnounceLevelUp", "filter": "data[\"idType\"] == \"player\" && data[\"key\"] == \"LEVEL\""}'
LEVELLobby 설정
샘플대로 따르려면 Lobby를 만들어야 합니다. Unity Cloud Dashboard의 Cloud Code 헬퍼 스크립트를 사용하여 진행할 수 있습니다.JavaScript
로비 ID를 기록해 둡니다.const { LobbyApi } = require("@unity-services/lobby-1.2");module.exports = async ({ params, context, logger }) => { const lobbyApi = new LobbyApi(context); const serviceId = "cloud-code"; try { // Create a private lobby without any initial players. const { data: lobby } = await lobbyApi.createLobby(serviceId, null, { name: "sample-lobby", maxPlayers: 4, }); return lobby.id; } catch (err) { logger.error(`Error while calling out to Lobby: ${JSON.stringify(err.message)}`); throw err; }};
로비에 플레이어 추가
다음 Cloud Code 스크립트를 실행하여 Unity Cloud Dashboard에서 만든 로비에 플레이어를 추가할 수 있습니다. 새 플레이어를 추가하려면 모든 테스트 실행에서 플레이어 ID 토큰을 재생성해야 합니다.
lobbyIdJavaScript
const { LobbyApi } = require("@unity-services/lobby-1.2");module.exports = async ({ params, context, logger }) => { const lobbyApi = new LobbyApi(context); const serviceId = "cloud-code"; try { await lobbyApi.joinLobbyById(params.lobbyId, serviceId, context.playerId); } catch (err) { logger.error("Failed to join lobby", { "error.message": err.message }, { lobbyId: params.lobbyId }); throw err; }};
결과 확인
결과를 확인하려면 푸시 메시지를 구독하는 Unity 프로젝트를 설정하고 이전에 생성한 플레이어 추가 Cloud Code 스크립트를 사용하여 인증된 플레이어가 로비에 참여할 수 있도록 합니다.필수 조건
푸시 메시지를 구독하려면 Cloud Code SDK를 설치하고 Unity Gaming Services 프로젝트를 Unity 에디터에 연결해야 합니다.프로젝트 연결
Unity Gaming Services 프로젝트를 Unity 에디터와 연결합니다. Unity Cloud Dashboard에서 UGS 프로젝트 ID를 확인할 수 있습니다.- Unity 에디터에서 Edit > Project Settings > Services를 선택합니다.
-
프로젝트를 연결합니다.
프로젝트에 Unity 프로젝트 ID가 없는 경우 다음 단계를 진행합니다.- Create a Unity Project ID > Organizations를 선택한 다음 드롭다운에서 조직을 선택합니다.
- Create project ID를 선택합니다.
Unity 프로젝트 ID가 있는 경우 다음 단계를 진행합니다.- Use an existing Unity project ID를 선택합니다.
- 드롭다운에서 조직과 프로젝트를 선택합니다.
- Link project ID를 선택합니다.
UnityEditor.CloudProjectSettings.projectIdSDK 설치
다음 단계를 따라 Unity 에디터용 최신 Cloud Code 패키지를 설치합니다.- Unity 에디터에서 Window > Package Manager를 엽니다.
- 패키지 관리자에서 Unity Registry 목록 뷰를 선택합니다.
- 를 검색하거나 목록에서 Cloud Code 패키지를 찾습니다.
com.unity.services.cloudcode - 패키지를 선택한 후 Install을 선택합니다.
Monobehaviour 스크립트 생성
플레이어 레벨 메시지를 구독하려면MonobehaviourMonoBehaviour처음으로using System;using System.Threading.Tasks;using Newtonsoft.Json;using Unity.Services.Authentication;using Unity.Services.CloudCode;using Unity.Services.CloudCode.Subscriptions;using Unity.Services.Core;using UnityEngine;namespace CloudCode{ public class CloudCodePushExample : MonoBehaviour { async void Start() { await UnityServices.InitializeAsync(); await AuthenticationService.Instance.SignInAnonymouslyAsync(); Debug.Log(AuthenticationService.Instance.PlayerId); await SubscribeToPlayerMessages(); } // This method creates a subscription to player messages and logs out the messages received, // the state changes of the connection, when the player is kicked and when an error occurs. Task SubscribeToPlayerMessages() { // Register callbacks, which are triggered when a player message is received var callbacks = new SubscriptionEventCallbacks(); callbacks.MessageReceived += @event => { Debug.Log(DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss.fffK")); Debug.Log( $"Got player subscription Message: {JsonConvert.SerializeObject(@event, Formatting.Indented)}"); }; callbacks.ConnectionStateChanged += @event => { Debug.Log( $"Got player subscription ConnectionStateChanged: {JsonConvert.SerializeObject(@event, Formatting.Indented)}"); }; callbacks.Kicked += () => { Debug.Log($"Got player subscription Kicked"); }; callbacks.Error += @event => { Debug.Log( $"Got player subscription Error: {JsonConvert.SerializeObject(@event, Formatting.Indented)}"); }; return CloudCodeService.Instance.SubscribeToPlayerMessagesAsync(callbacks); } }}
Monobehaviour로비 참여
이전에 생성한 플레이어 추가 Cloud Code 스크립트를 사용하여 인증된 플레이어가 로비에 참여하도록 할 수 있습니다. 이전에 생성한 로비 ID를lobbyIdplayerIdCloud Save에서 Level 키 업데이트
다음 스크립트를 실행하여 Cloud Code 모듈을 트리거하도록 Cloud Save 키를 업데이트할 수 있습니다.playerIdlevel
앞서 로비에 추가한 플레이어의 ID를 사용합니다. 이렇게 하면 Unity 프로젝트에서 인증된 플레이어가 동일한 로비에 있으므로 해당 플레이어에게 메시지가 전송됩니다.
JavaScript
const { DataApi } = require("@unity-services/cloud-save-1.4");module.exports = async ({ params, context, logger }) => { const cloudSaveApi = new DataApi(context); try { await cloudSaveApi.setItem(context.projectId, params.playerId, { key: "LEVEL", value: params.level, }); result = await cloudSaveApi.getItems(context.projectId, params.playerId); return result.data; } catch (err) { logger.error("Error while calling out to Cloud Save", { "error.message": err.message }); throw err; }};
결과 확인
Unity 프로젝트가 실행 중이고 Unity 프로젝트의 인증된 플레이어가 로비에 있는지 확인하고, Cloud Save의LEVELGot player subscription Message:{ "data_base64": <BASE64-ENCODED-DATA>, "time": "2023-11-13T16:21:35.102058117Z", "message": "The player Z96pNb4wfgdaMLqMQfWpwXEclaRZ has leveled up!", "specversion": "1.0", "id": <ID>, "source": "https://cloud-code.service.api.unity.com", "type": "com.unity.services.cloud-code.push.v1", "projectid": <PROJECT-ID>, "environmentid": <ENVIRONMENT-ID>, "correlationid": <CORRELATION-ID>, "messagetype": "Level up!",}