기술 자료

​
​

Development

User Acquisition

Monetization

산업 분야

Cloud Save

Unity SDK tutorial

Cloud Save for Cloud Code

Open Unity Dashboard

Cloud Save

LiveOps
​
​
Cloud Save
  • Overview
  • Get started
  • Concepts
  • Tutorials
    • Unity SDK tutorial
    • Unity SDK sample
    • Cloud Save for Cloud Code
    • Cloud Save Dashboard
    • REST API tutorial
  • Reference
  • Privacy and consent
  1. Cloud Save

Unity SDK 샘플

Refer to sample code that shows how to save and load data with the Cloud Save Software Development Kit.
읽는 시간 7분
최근 업데이트: 8달 전

이 샘플은 Cloud Save SDK를 사용하여 데이터를 저장하고 로드하는 방법을 보여 줍니다.
Unity에서 Package Manager > Cloud Save > Samples를 선택하여 샘플을 확인할 수 있습니다.
using System;using System.Collections.Generic;using System.IO;using System.Text;using System.Threading.Tasks;using Unity.Services.Authentication;using Unity.Services.CloudSave;using Unity.Services.CloudSave.Models;using Unity.Services.Core;using UnityEngine;namespace CloudSaveSample{ [Serializable] public class SampleObject { public string SophisticatedString; public int SparklingInt; public float AmazingFloat; } public class CloudSaveSample : MonoBehaviour { private async void Awake() { // Cloud Save needs to be initialized along with the other Unity Services that // it depends on (namely, Authentication), and then the user must sign in. await UnityServices.InitializeAsync(); await AuthenticationService.Instance.SignInAnonymouslyAsync(); // Player Data // first set of data saved without a write lock await ForceSaveSingleData("primitive_key", "value!"); SampleObject firstSample = new SampleObject { AmazingFloat = 13.37f, SparklingInt = 1337, SophisticatedString = "hi there!" }; string objectKey = "object_key"; string writeLock = await ForceSaveObjectData(objectKey, firstSample); SampleObject incomingSample = await RetrieveSpecificData<SampleObject>(objectKey); Debug.Log( $"Loaded sample object: {incomingSample.AmazingFloat}, {incomingSample.SparklingInt}, {incomingSample.SophisticatedString}, write lock {writeLock}" ); // second set of data saved with a write lock SampleObject secondSample = new SampleObject { AmazingFloat = 42.26f, SparklingInt = 4226, SophisticatedString = "hi there... again!" }; string updatedWriteLock = await SaveObjectData(objectKey, secondSample, writeLock); SampleObject updatedSample = await RetrieveSpecificData<SampleObject>(objectKey); Debug.Log( $"Loaded updated sample object: {updatedSample.AmazingFloat}, {updatedSample.SparklingInt}, {updatedSample.SophisticatedString}, write lock {updatedWriteLock}" ); // deletion with wrong write lock, this will fail with a validation error await DeleteSpecificData(objectKey, "incorrect-write-lock"); // force delete without write lock await ForceDeleteSpecificData(objectKey); await ListAllKeys(); await RetrieveEverything(); // Custom Data, read-only string customTestId = "custom-test-id"; await ListAllCustomKeys(customTestId); await RetrieveAllCustomData(customTestId); // Files var inputBytes = Encoding.UTF8.GetBytes("test content for file bytes"); var inputStream = new MemoryStream( Encoding.UTF8.GetBytes("test content for file stream") ); string bytesFileKey = "bytes-test-file"; string streamFileKey = "stream-test-file"; await SaveFileBytes(bytesFileKey, inputBytes); await SaveFileStream(streamFileKey, inputStream); await ListAllFiles(); await GetFileMetadata(bytesFileKey); await GetFileMetadata(streamFileKey); var fileBytes = await LoadFileBytes(bytesFileKey); Debug.Log( $"Loaded sample file containing content: {Encoding.UTF8.GetString(fileBytes)}" ); using var fileStream = await LoadFileStream(streamFileKey); using var streamReader = new StreamReader(fileStream); Debug.Log( $"Loaded sample file containing content: {await streamReader.ReadToEndAsync()}" ); await DeleteFile(bytesFileKey); await DeleteFile(streamFileKey); } private async Task ListAllKeys() { try { var keys = await CloudSaveService.Instance.Data.Player.ListAllKeysAsync(); Debug.Log($"Keys count: {keys.Count}\n" + $"Keys: {String.Join(", ", keys)}"); } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } private async Task ListAllCustomKeys(string customId) { try { var keys = await CloudSaveService.Instance.Data.Custom.ListAllKeysAsync(customId); Debug.Log( $"Keys count for custom ID {customId}: {keys.Count}\n" + $"Keys: {String.Join(", ", keys)}" ); } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } private async Task ForceSaveSingleData(string key, string value) { try { Dictionary<string, object> oneElement = new Dictionary<string, object>(); // It's a text input field, but let's see if you actually entered a number. if (Int32.TryParse(value, out int wholeNumber)) { oneElement.Add(key, wholeNumber); } else if (Single.TryParse(value, out float fractionalNumber)) { oneElement.Add(key, fractionalNumber); } else { oneElement.Add(key, value); } // Saving the data without write lock validation by passing the data as an object instead of a SaveItem Dictionary<string, string> result = await CloudSaveService.Instance.Data.Player.SaveAsync(oneElement); Debug.Log( $"Successfully saved {key}:{value} with updated write lock {result[key]}" ); } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } private async Task<string> ForceSaveObjectData(string key, SampleObject value) { try { // Although we are only saving a single value here, you can save multiple keys // and values in a single batch. Dictionary<string, object> oneElement = new Dictionary<string, object> { { key, value } }; // Saving data without write lock validation by passing the data as an object instead of a SaveItem Dictionary<string, string> result = await CloudSaveService.Instance.Data.Player.SaveAsync(oneElement); string writeLock = result[key]; Debug.Log($"Successfully saved {key}:{value} with updated write lock {writeLock}"); return writeLock; } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } return null; } private async Task<string> SaveObjectData(string key, SampleObject value, string writeLock) { try { // Although we are only saving a single value here, you can save multiple keys // and values in a single batch. // Use SaveItem to specify a write lock. The request will fail if the provided write lock // does not match the one currently saved on the server. Dictionary<string, SaveItem> oneElement = new Dictionary<string, SaveItem> { { key, new SaveItem(value, writeLock) } }; // Saving data with write lock validation by using a SaveItem with the write lock specified Dictionary<string, string> result = await CloudSaveService.Instance.Data.Player.SaveAsync(oneElement); string newWriteLock = result[key]; Debug.Log( $"Successfully saved {key}:{value} with updated write lock {newWriteLock}" ); return newWriteLock; } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } return null; } private async Task<T> RetrieveSpecificData<T>(string key) { try { var results = await CloudSaveService.Instance.Data.Player.LoadAsync( new HashSet<string> { key } ); if (results.TryGetValue(key, out var item)) { return item.Value.GetAs<T>(); } else { Debug.Log($"There is no such key as {key}!"); } } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } return default; } private async Task RetrieveEverything() { try { // If you wish to load only a subset of keys rather than everything, you // can call a method LoadAsync and pass a HashSet of keys into it. var results = await CloudSaveService.Instance.Data.Player.LoadAllAsync(); Debug.Log($"{results.Count} elements loaded!"); foreach (var result in results) { Debug.Log($"Key: {result.Key}, Value: {result.Value.Value}"); } } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } private async Task RetrieveAllCustomData(string customId) { try { // If you wish to load only a subset of keys rather than everything, you // can call a method LoadAsync and pass a HashSet of keys into it. var results = await CloudSaveService.Instance.Data.Custom.LoadAllAsync(customId); Debug.Log($"{results.Count} elements loaded from custom Id {customId}!"); foreach (var result in results) { Debug.Log($"Key: {result.Key}, Value: {result.Value.Value}"); } } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } private async Task ForceDeleteSpecificData(string key) { try { // Deletion of the key without write lock validation by omitting the DeleteOptions argument await CloudSaveService.Instance.Data.Player.DeleteAsync(key); Debug.Log($"Successfully deleted {key}"); } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } private async Task DeleteSpecificData(string key, string writeLock) { try { // Deletion of the key with write lock validation await CloudSaveService.Instance.Data.Player.DeleteAsync( key, new DeleteOptions { WriteLock = writeLock } ); Debug.Log($"Successfully deleted {key}"); } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } private async Task ListAllFiles() { try { var results = await CloudSaveService.Instance.Files.Player.ListAllAsync(); Debug.Log("Metadata loaded for all files!"); foreach (var element in results) { Debug.Log($"Key: {element.Key}, File Size: {element.Size}"); } } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } private async Task GetFileMetadata(string key) { try { var results = await CloudSaveService.Instance.Files.Player.GetMetadataAsync(key); Debug.Log("File metadata loaded!"); Debug.Log($"Key: {results.Key}, File Size: {results.Size}"); } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } private async Task SaveFileBytes(string key, byte[] bytes) { try { await CloudSaveService.Instance.Files.Player.SaveAsync(key, bytes); Debug.Log("File saved!"); } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } private async Task SaveFileStream(string key, Stream stream) { try { await CloudSaveService.Instance.Files.Player.SaveAsync(key, stream); Debug.Log("File saved!"); } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } private async Task<byte[]> LoadFileBytes(string key) { try { var results = await CloudSaveService.Instance.Files.Player.LoadBytesAsync(key); Debug.Log("File loaded!"); return results; } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } return null; } private async Task<Stream> LoadFileStream(string key) { try { var results = await CloudSaveService.Instance.Files.Player.LoadStreamAsync(key); Debug.Log("File loaded!"); return results; } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } return null; } private async Task DeleteFile(string key) { try { await CloudSaveService.Instance.Files.Player.DeleteAsync(key); Debug.Log("File deleted!"); } catch (CloudSaveValidationException e) { Debug.LogError(e); } catch (CloudSaveRateLimitedException e) { Debug.LogError(e); } catch (CloudSaveException e) { Debug.LogError(e); } } }}

Copyright © 2026 Unity Technologies
법률 정보개인정보 처리방침쿠키Documentation Terms of Use개인 정보 판매 또는 공유 금지개인정보 보호 선택(쿠키 설정)

'Unity', Unity 로고 및 기타 Unity 상표는 미국 및 기타 지역 내 Unity Technologies 또는 그 계열사의 상표 또는 등록상표입니다(자세한 내용은 여기에서 확인하세요). 기타 명칭 또는 브랜드는 해당 소유자의 상표입니다.

일부 페이지는 편의를 위해 기계 번역되었으며 부정확한 내용이 있을 수 있습니다. 정보가 상충되는 경우, 영어 버전을 우선으로 참조하세요.


    이 페이지의 문제 보고