読者です 読者をやめる 読者になる 読者になる

kidoOooOoooOOom

IT系で開発やってます

UnityでScriptableObjectを用いて設定管理

Unity

拡張エディタやImporterの設定ファイルとして、ScriptableObjectが使用できる。
tsubakit1.hateblo.jp


例えば今回は、画像ファイルをUnity上にインポートする際に、特定のフォルダ配下の場合はTrue color にしたりmip mapをOFFにするといった自動設定を行うため、下記のようなScriptableObjectを用意する。

    [CreateAssetMenu(fileName = "TextureImporterConfig")]
    public class TextureImporterConfig : ScriptableObject, ISerializationCallbackReceiver
    {
        public List<TextureSetting> textureSettings = new List<TextureSetting> ();

        public Dictionary<string, TextureSetting> textureSettingsDic;

        public void OnAfterDeserialize()
        {
            textureSettingsDic = new Dictionary<string, TextureSetting> ();

            foreach (var item in textureSettings)
            {
                if (textureSettingsDic.ContainsKey(item.targetPath) == false)
                {
                    textureSettingsDic.Add(item.targetPath, item);
                }
            }
        }

        public void OnBeforeSerialize()
        {
        }
    }

    [System.Serializable]
    public class TextureSetting
    {
        public string targetPath;
        public TextureImporterType importType;
        public bool mipmapEnabled;
        public TextureImporterFormat importFormat;
        public string packingTag;
    }


CreateAssetMenu属性を付随すると、Asset Menuでこのclassのオブジェクトを生成できるようになる。
ただし、ScriptableObjectはDictionary型を直接シリアライズできないので、List型で一旦保持しておき、ISerializationCallbackReceiverのOnAfterDeserialize()の中でDictionary型へ変換するようにした。

これでUnity Editor上でも設定を変更できるようになったのだが、Editor上での変更が一向にassetファイルに反映されなかった。
調べてみると、自分で SetDirty をして変更通知をしてから asset を 保存するのが必要だった。
docs.unity3d.com

というわけで下記クラスを追加し、Editor上で Save Asset ボタンを押すと変更内容がassetファイルに反映されるようにした。

    [CustomEditor(typeof(TextureImporterConfig))]
    public class TextureImporterConfigEditor : Editor
    {
        public override void OnInspectorGUI()
        {
            DrawDefaultInspector();

            if (GUILayout.Button("Save Asset"))
            {
                TextureImporterConfig configTarget = target as TextureImporterConfig;
                EditorUtility.SetDirty(configTarget);
                AssetDatabase.SaveAssets();
            }
        }
    }