文档

​
​

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.
阅读时间8 分钟
最后更新于 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
法律信息隐私政策CookiesDocumentation Terms of Use请勿出售或分享我的个人信息您的隐私选择(Cookie 设置)

“Unity”、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属公司在美国和其他地方的商标或注册商标(此处查看更多信息)。其他名称或品牌是其各自所有者的商标。

为方便起见,一些页面是机器翻译的,可能包含不准确的内容。如有信息不一致的情况,以英文版本为准。


    报告此页面的问题