You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中借助Google Play Games插件保存多变量的方法咨询

Solution: Expand Google Play Games Saved Games to Store Multiple Values in Unity

Nice work getting the single float save up and running! Let’s build on that tutorial code to handle a full set of variables—this just requires wrapping your save data into a serializable object and adjusting how you serialize/deserialize it for GPG’s API. Here’s a step-by-step breakdown:

Step 1: Create a Serializable Save Data Class

First, define a class to hold all the variables you need to save. Mark it with [Serializable] so Unity can convert it to a storable format:

using System;
using UnityEngine;

[Serializable]
public class GameSaveData
{
    // Add all your saveable variables here—mix and match types as needed
    public float playerHealth;
    public float totalScore;
    public int currentLevel;
    public string playerUsername;
    public float[] resourceAmounts; // Example array of floats
}

Step 2: Update the Save Method

Instead of saving a single float, we’ll serialize our GameSaveData object into a byte array (using Unity’s JsonUtility for simplicity) and store that in GPG:

public void SaveGame(GameSaveData saveData)
{
    // Convert save data to a JSON string
    string jsonData = JsonUtility.ToJson(saveData);
    // Convert string to byte array for GPG storage
    byte[] byteData = System.Text.Encoding.UTF8.GetBytes(jsonData);

    // Use GPG's saved games API to commit the data
    PlayGamesPlatform.Instance.SavedGame.OpenWithAutomaticConflictResolution(
        "main_save_slot", // Your save slot name (can adjust this for multiple slots)
        DataSource.ReadCacheOrNetwork,
        ConflictResolutionStrategy.UseLongestPlaytime,
        (status, saveGame) =>
        {
            if (status == SavedGameRequestStatus.Success)
            {
                saveGame.CommitUpdate(byteData, TimeSpan.FromMinutes(PlayGamesPlatform.Instance.GetPlaytime()), 
                    (updateStatus) =>
                    {
                        if (updateStatus == SavedGameRequestStatus.Success)
                        {
                            Debug.Log("Save completed successfully!");
                        }
                        else
                        {
                            Debug.LogError("Save failed: " + updateStatus);
                        }
                    });
            }
            else
            {
                Debug.LogError("Failed to open save slot: " + status);
            }
        });
}

Step 3: Update the Load Method

When loading, we’ll pull the byte array from GPG, convert it back to JSON, then deserialize it into our GameSaveData object:

public void LoadGame(Action<GameSaveData> onLoadFinished)
{
    PlayGamesPlatform.Instance.SavedGame.OpenWithAutomaticConflictResolution(
        "main_save_slot",
        DataSource.ReadCacheOrNetwork,
        ConflictResolutionStrategy.UseLongestPlaytime,
        (status, saveGame) =>
        {
            if (status == SavedGameRequestStatus.Success)
            {
                saveGame.ReadBinaryData((readStatus, byteData) =>
                {
                    if (readStatus == SavedGameRequestStatus.Success)
                    {
                        // Convert byte array back to JSON string
                        string jsonData = System.Text.Encoding.UTF8.GetString(byteData);
                        // Deserialize into GameSaveData object
                        GameSaveData loadedData = JsonUtility.FromJson<GameSaveData>(jsonData);
                        onLoadFinished?.Invoke(loadedData);
                        Debug.Log("Load completed successfully!");
                    }
                    else
                    {
                        Debug.LogError("Failed to read save data: " + readStatus);
                        onLoadFinished?.Invoke(null);
                    }
                });
            }
            else
            {
                Debug.LogError("Failed to open save slot: " + status);
                onLoadFinished?.Invoke(null);
            }
        });
}

Step 4: Use the Updated Methods

Now you can populate and save your data, then load it back to update your game state:

// Example: Saving your game state
GameSaveData currentSave = new GameSaveData();
currentSave.playerHealth = 85.5f;
currentSave.totalScore = 12500.0f;
currentSave.currentLevel = 7;
currentSave.resourceAmounts = new float[] { 10.0f, 3.5f, 0.0f };
SaveGame(currentSave);

// Example: Loading the saved state
LoadGame((loadedData) =>
{
    if (loadedData != null)
    {
        // Apply loaded values to your game
        Debug.Log("Loaded health: " + loadedData.playerHealth);
        Debug.Log("Loaded level: " + loadedData.currentLevel);
    }
});

Important Notes

  • Serializable Types: Stick to Unity-serializable variables (primitives, arrays, lists of serializable types, Vector3, etc.). Avoid saving references to GameObjects or non-serializable objects—save data you can use to recreate the state instead.
  • Conflict Resolution: The tutorial uses UseLongestPlaytime, but you can switch to UseMostRecent or another strategy if it fits your game better.
  • Async Operations: GPG save/load calls are asynchronous, so always use the callback methods to handle completion—don’t try to use loaded data immediately after calling LoadGame.

内容的提问来源于stack exchange,提问作者Nicolas Decelle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:59:01