Menu
CoddyTech

読み込みとデフォルト値

CoddyのUnityジャーニー「Unityにおけるゲームアーキテクチャ」セクションの一部。レッスン 26/50。

読み込みでは、存在しないセーブや不完全なセーブにも対処する必要があります。レースゲームは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を読み込み、Spaceキーを押すとペットに餌を与えて保存します。読み込みには2つの問題があります。

  • 新しいプレイヤーはpet.jsonを持っておらず、StartでFileNotFoundExceptionが発生して停止します。ファイルがない場合は、Inspectorで設定したペット(Biscuit、空腹度30、幸福度80、Ball)をそのまま使い、A new pet: Biscuitとログに出力してください。
  • ゲームのバージョン1ではpetNameとhungerだけが保存され、happinessとtoysはバージョン2で追加されました(PetSave.csを参照)。古いセーブデータをFromJsonで読み込むと、Inspectorの値ではなく、クラスの既定値である50とおもちゃなしになります。既存のファイルをJsonUtility.FromJsonOverwriteでpetに読み込み、ファイルに含まれていない値はInspectorの値のままになるようにし、読み込んだ名前を使って、Welcome back, Mochiのように歓迎メッセージをログに出力してください。

Playを押してペットに餌を与え、次にStopを押してからもう一度Playを押し、その後Checkを押してください。

自分で試してみよう

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;
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

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