検証環境
- Unity 2018.4.8f1
概要
using UnityEngine; public class Example : ScriptableObject { private string[] m_list; public string[] List { get { // はじめてアクセスされたら配列を作成する if ( m_list == null || m_list.Length <= 0 ) { m_list = new[] { "フシギダネ", "フシギソウ", "フシギバナ", }; } return m_list; } } }
例えば上記のように ScriptableObject に private な配列を定義して
プロパティにはじめてアクセスされた時に配列を作成するようにして
using UnityEngine; public class TestScene : MonoBehaviour { public Example m_example; private void Awake() { var list = m_example.List; } }
他のクラスからそのプロパティにアクセスした場合、
Unity 再生中のみ配列の値が保持されると思っていたのですが、
Unity の再生を停止して、Inspector を Debug モードで見てみると
配列に設定した値が保持されていました
using UnityEngine; public class Example : ScriptableObject { private string[] m_list; public string[] List { get { // 配列の値が保持されてしまっているため // null や空配列のチェックで if 文の中に入らない if ( m_list == null || m_list.Length <= 0 ) { m_list = new[] { // そのため、配列に設定する値を変更しても // ここの処理には絶対に入ってこない "ヒトカゲ", "リザード", "リザードン", }; } // そして、すでに保持されてしまっている値が返される return m_list; } } }
そのため、上記のようにプロパティにはじめてアクセスされた時に
配列に設定する値を変えても、すでに前回設定した値が保持されてしまっているため、
その古い値が常に返却されてしまいます
(Unity エディタを起動し直すと、保持されている値は破棄されます)
対策
[NonSerialized] private string[] m_list;
値を保持してほしくない private 変数に NonSerialized 属性を適用すると
シリアライズされなくなるため、Unity の再生中以外は値が保持されなくなります