Menu
CoddyTech

読み込みと初期値

CoddyのUnityジャーニー「Unityのゲームアーキテクチャ」セクションの一部。レッスン 32/64。

読み込みでは、存在しないセーブデータや不完全なセーブデータにも対応する必要があります。レースゲームでは RaceSave を保存します。ゲームのバージョン 2 で musicVolume が追加されました。

[System.Serializable]
public class RaceSave
{
    public int trophies;
    public string car = "Rookie Kart";
    public float musicVolume = 0.8f;
}
RaceSave save;
if (File.Exists(path))
{
    save = JsonUtility.FromJson<RaceSave>(File.ReadAllText(path));
}
else
{
    save = new RaceSave();
}

新しいプレイヤーにはファイルがありません。また、ファイルが存在しない状態で File.ReadAllText を実行すると FileNotFoundException が発生するため、まず File.Exists を確認し、new RaceSave() から始めます。フィールド初期化子により、トロフィーは 0、車は Rookie Kart、音量は 0.8 になります。以前からのプレイヤーのバージョン 1 のファイルには、{"trophies":3,"car":"Red Racer"} が含まれています。FromJson は新しい RaceSave を作成し、フィールド初期化子を実行してから、JSON にあるキーだけを設定するため、musicVolume は 0.8 になります。クラスに対応するフィールドがないキーは無視されます。そのため、新しいフィールドすべてに妥当な値の初期化子があれば、新しいバージョンのゲームでも古いセーブデータを読み込めます。

JsonUtility.FromJsonOverwrite(json, obj) はオブジェクトを新しく作るのではなく、すでに存在するオブジェクトに値を設定し、JSON にないフィールドはすべてそのままにします。FromJson では MonoBehaviour や ScriptableObject を作成できません(Unity は Cannot deserialize JSON to new instances of type 'RaceSettings.' をスローします)。そのため、設定アセットは上書きして読み込みます。JsonUtility.FromJsonOverwrite(json, settings);。上書きでは、Inspector で設定された値など、オブジェクトがすでに保持している値も維持されます。一方、FromJson ではクラスの初期化子の値に戻ります。

challenge icon

チャレンジ

中級

新しいプレイヤーや古いセーブデータでも安全にpet.jsonを読み込みます。

  1. Start()で、FromJsonの行をif (File.Exists(path))とelseに置き換えます。
  2. ファイルがある場合は、Inspectorのpetに値を読み込みます: JsonUtility.FromJsonOverwrite(File.ReadAllText(path), pet);。次にpet.petNameを使ってWelcome back, Mochiとログに出力します。
  3. ファイルがない場合は、同じ方法でA new pet: Biscuitとログに出力します。

「プレイ」を押してペットに餌をあげたら、「停止」を押してからもう一度「プレイ」を押します。「おかえりなさい」と表示されます。その後、「確認」を押します。

自分で試してみよう

using System.IO;
using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;

public class PetCare : MonoBehaviour
{
    public PetSave pet;
    public TMP_Text petText;
    private string path;

    void Start()
    {
        path = Path.Combine(Application.persistentDataPath, "pet.json");
        pet = JsonUtility.FromJson<PetSave>(File.ReadAllText(path));
        Show();
    }

    void Update()
    {
        if (Keyboard.current.spaceKey.wasPressedThisFrame)
        {
            pet.hunger = Mathf.Max(pet.hunger - 10, 0);
            pet.happiness = Mathf.Min(pet.happiness + 5, 100);
            File.WriteAllText(path, JsonUtility.ToJson(pet));
            Show();
        }
    }

    void Show()
    {
        petText.text = pet.petName + ": hunger " + pet.hunger + ", happiness " + pet.happiness;
    }
}

Unityのゲームアーキテクチャのすべてのレッスン

自分で練習してみよう: Unityプレイグラウンド