うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】ScriptableObject のフィールドは再生を終了しても保存される

ScriptableObject を利用してパラメータを管理すると値を変更した際にリコンパイルが不要なのでお手軽ですが、

NonSerialized な属性をつけていないフィールドは Unity を再起動するまで値を保持し続けるので注意が必要になる

例えば以下のような ScriptableObject を利用しているとして再生のたびに Initialize を呼び出してみる

using System;
using UnityEngine;

public class SampleScriptableObject : ScriptableObject
{
    private int IntValue;
    [NonSerialized]
    private int IntValueNon;
    
    private string Stringvalue;
    [NonSerialized]
    private string StringvalueNon;
    
    private Vector2 Vector2Value;
    [NonSerialized]
    private Vector2 Vector2ValueNon;
    
    private Sample SampleClass;
    [NonSerialized]
    private Sample SampleClassNon;

    [Serializable]
    private class Sample { }

    public void Initialize()
    {
        Debug.Log($"----Call----");
        Debug.Log($"Int: {IntValue} Non: {IntValueNon}");
        Debug.Log($"String: {Stringvalue} Non: {StringvalueNon}");
        Debug.Log($"Vector2: {Vector2Value} Non: {Vector2ValueNon}");
        Debug.Log($"Class: {SampleClass != null} Non: {SampleClassNon != null}");

        IntValue = 1;
        IntValueNon = 1;
        Stringvalue = "a";
        StringvalueNon = "a";
        Vector2Value = Vector2.one;
        Vector2ValueNon = Vector2.one;
        SampleClass = new Sample();
        SampleClassNon = new Sample();
    }
}

2回実行したあとのログが以下になる

見てわかるように NonSerialized の属性がないフィールドは前の値を保持し続けてしまっている

そのため、再生のたびに初期化したいフィールドには、属性をちゃんと定義する必要がある


Inspector の Debug を利用すると値を確認することができる

Enter Play Mode Settings の注意

Unity2019.3 から Enter Play Mode Options を利用することで UnityEditor 上の再生が始まるまでの時間を短縮することができます

しかし、これを利用していた場合は NonSerialized を定義していたとしても初期化されないので注意が必要になる