게임 아이디어와 기능

다음에 추가할 기능

플레이어 우편함

개별 알림과 프로젝트 공지를 보호된 보상 및 통합 소셜 폴링으로 제공합니다.

SDK: develop 브랜치플레이어 세션 필요
Unity
플레이어 우편함 일러스트
확인할 수 있는 결과

게임이 개별 메시지와 공지를 표시하고 읽음 처리하며 각 보호 보상을 최대 한 번 수령합니다.

동영상 준비 중

이 단계의 동영상은 아직 없습니다. 안내와 MCP 요청은 바로 사용할 수 있습니다.

플레이어 우편함

같은 프로젝트 준비

  1. 게임 설정과 같은 프로젝트를 대시보드에서 선택하세요.

    플레이어 우편함 →
  2. 첫 요청에는 추가 정의가 필요하지 않습니다. 일치하는 게임 데이터가 없으면 빈 결과도 정상입니다.

    프로젝트에 일반 텍스트 공지를 게시하기 전에 테스트 플레이어를 등록하세요. 같은 플레이어로 수신함을 읽으세요.

    게시 시점까지 등록되었고 현재 활성 상태인 프로젝트 플레이어가 대상입니다. 이전에 비활성이던 플레이어도 다시 활성화되면 대상이 될 수 있습니다. 이후 등록자는 제외됩니다.

이 기능 구현하기

가이드는 미리 볼 수 있습니다. 실행하려면 활성 프로젝트 키가 필요합니다. 프로젝트 준비

SDK 설치와 프로젝트 설정 가져오기가 완료되고 플레이어가 로그인해야 합니다.

이 SDK 예제는 develop을 사용합니다. 필요한 API가 설치된 SDK에 있는지 확인하세요.

빠른 시작으로 원하는 플레이어를 연결하세요. 명시적인 버튼이나 씬 동작에서 RunReviewedAction()을 호출하세요. 파일을 여는 것만으로는 요청을 보내지 않습니다.

C#
Assets/Scripts/InboxDemo.cs
horizOn 호출
1using PM.horizOn.Cloud.Objects.Network.Responses;
2using UnityEngine;
3using PM.horizOn.Cloud.Core;
4using PM.horizOn.Cloud.Manager;
5​
6// Existing SDK/project configuration and authenticated player session required.
7// Call RunReviewedAction explicitly after reviewing this example and its data.
8// 현재 플레이어의 인증된 세션을 사용하세요. 수령 결과가 불확실하면 같은 항목 ID로 다시 시도합니다. 서버 상태로 값을 교체하고
9// 보상을 두 번 더하지 마세요.
10public sealed class InboxDemo : MonoBehaviour
11{
12 public async void RunReviewedAction()
13 {
14 var sessionUser = UserManager.Instance.CurrentUser;
15 if (sessionUser == null || !sessionUser.IsValid()) return;
16 var userId = UserManager.Instance.CurrentUser.UserId;
17 var manager = InboxManager.Instance;
18 var loaded = await manager.GetInbox(userId, since: null);
19 if (!loaded.IsSuccess) { Debug.LogWarning(loaded.ErrorCode); return; }
20 foreach (var entry in loaded.Data.entries) Debug.Log(entry.textKey);
21 // The manager retains full cached entries when the wire response is unchanged.
22 // Poll again only after loaded.Data.pollAfterSeconds, and stop with the game lifecycle.
23​
24 bool claimInFlight = false;
25 async System.Threading.Tasks.Task ClaimSelectedReward(string entryId)
26 {
27 if (claimInFlight) return;
28 const string projectId = "YOUR_PROJECT_ID";
29 string pendingKey = "horizOn_inbox_claim_" + projectId + "_" + userId;
30 string pending = PlayerPrefs.GetString(pendingKey, "");
31 if (pending.Length > 0 && pending != entryId) return; // Resolve the original claim first.
32 if (pending.Length == 0)
33 {
34 var current = manager.CurrentInbox; // Authorized for the current project/session.
35 if (current == null || current.userId != userId) return;
36 var selected = System.Array.Find(current.entries, entry => entry.id == entryId);
37 if (selected == null || selected.claimed || selected.attachment?.values == null ||
38 selected.attachment.values.Length == 0) return;
39 }
40 // Previously saved IDs remain replayable even after their visible state changes.
41 PlayerPrefs.SetString(pendingKey, entryId);
42 PlayerPrefs.Save();
43 if (PlayerPrefs.GetString(pendingKey) != entryId) return;
44 claimInFlight = true;
45 try
46 {
47 var claimed = await manager.Claim(userId, entryId);
48 if (!claimed.IsSuccess) { Debug.LogWarning(claimed.ErrorCode); return; }
49 // Display claimed.Data.inbox and replace values with claimed.Data.playerValues.
50 // The SDK refreshes its cache. Never add reward deltas yourself.
51 if (PlayerPrefs.GetString(pendingKey, "") == entryId)
52 {
53 PlayerPrefs.DeleteKey(pendingKey);
54 PlayerPrefs.Save();
55 }
56 }
57 finally { claimInFlight = false; }
58 }
59 // Invoke ClaimSelectedReward only from an explicit player action.
60 // Retry the saved entryId after a lost response; no replacement grant or new action ID.
61 // Other deliberate actions: await manager.MarkRead(userId, entryId);
62 // await manager.Remove(userId, entryId); // Protects unclaimed rewards.
63 }
64}
전체 SDK 예제 열기 ↗

새 기능을 테스트하세요.

게임이 개별 메시지와 공지를 표시하고 읽음 처리하며 각 보호 보상을 최대 한 번 수령합니다.

게임 설정과 같은 프로젝트를 대시보드에서 선택하세요.

엔드포인트
  • GET/inbox
  • POST/inbox/read
  • POST/inbox/claim
  • POST/inbox/remove
API 레퍼런스의 모든 엔드포인트
다음 단계에 대한 추천

모든 라운드에 최고 점수를 더하세요.

라운드가 끝나면 점수를 저장하고 선두를 보여주세요. 기존 연결과 플레이어 세션을 계속 사용하세요.