Unity

Unityを5.3.xにアップデートしたらInspectorの変更が保存されなくなってしまった…。 (´・ω・`)

More than 1 year has passed since last update.

概要

Editor拡張してInspectorの表示をカスタムしていたのですが、Unityを5.3.xにアップデートしたらその値が保存されなくなってしまった、というお話を綴ります。

※尚、まだ充分な調査/検証ができていないです。

事例

サンプルコード : 保存されない(旧来)Ver.

TestClass.cs
using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
#endif

/* -- 基礎クラス -- */
public class TestClass : MonoBehaviour
{
    [SerializeField]
    int     myInt   = 0;


#if UNITY_EDITOR
    /* -- Editor拡張クラス -- */
    [CustomEditor(typeof(TestClass))]
    public class TestClassEditor : Editor
    {
        public override void OnInspectorGUI()
        {
            TestClass tc = target as TestClass;

            tc.myInt = EditorGUILayout.IntField( tc.myInt );
        }
    }
#endif
}

サンプルコード : 保存される(模索)Ver.

TestClass.cs
using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
#endif

/* -- 基礎クラス -- */
public class TestClass : MonoBehaviour
{
    [SerializeField]
    int     myInt   = 0;


#if UNITY_EDITOR
    /* -- Editor拡張クラス -- */
    [CustomEditor(typeof(TestClass))]
    public class TestClassEditor : Editor
    {
        // 経由用
        SerializedProperty intProperty;

        void OnEnable()
        {
            // 基礎クラスからmyIntをSerializedPropertyで受け取る
            intProperty = serializedObject.FindProperty( "myInt" );
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            // 編集中はSerializedProperty経由で
            intProperty.intValue = EditorGUILayout.IntField( intProperty.intValue );

            serializedObject.ApplyModifiedProperties();
        }
    }
#endif
}

基礎クラスのパラメタを SerializedProperty 経由で取り扱い、 ApplyModifiedProperties() することで保存されるようになるみたい。

もしかしてEditor拡張ってこの手法がメジャーなのかな…?

これ使うと、パラメタの変更がUnity側に検知される(閉じるときにセーブするか訊かれる)し、Undoもできる…!

問題点/懸念点

  • 拡張パラメタが多いとリプレイスするのがしんどい
  • そもそもこの現象が仕様なのかバグなのか判らない

↑に対するとりあえずの打開案

色々手探りしているうちに、 SaveScene() 呼ぶとちゃんと保存されることに気が付いたので、セーブボタンつけてみたよ。

サンプルコード : 旧来Ver.向け打開案

TestClass.cs
using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.SceneManagement;  //!< 追加
#endif

public class TestClass : MonoBehaviour
{
    [SerializeField]
    int     myInt   = 0;


#if UNITY_EDITOR
    /** -- Editor拡張クラス -- */
    [CustomEditor(typeof(TestClass))]
    public class TestClassEditor : Editor
    {
        public override void OnInspectorGUI()
        {
            TestClass tc = target as TestClass;

            tc.myInt = EditorGUILayout.IntField( tc.myInt );

            // セーブボタン (マルチシーン?知らない子ですね。)
            if( GUILayout.Button( "Save!!" ) )
                EditorSceneManager.SaveScene( EditorSceneManager.GetActiveScene() );
        }
    }
#endif
}

結局、Ctrl+Sとかではセーブできていないんだけど、
既にいっぱいあるパラメタを全部SerializedPropertyに置き換えるよりは簡単かなって…。

(書いてて思ったけど、このSceneManager辺りの改修が影響してたりするのかな…?)

何かわかったらまた追記する(かも)よ!