コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】CanEditMultipleObjects 属性を適用したエディタ拡張で選択中のすべてのオブジェクトのパラメータを更新する方法

概要

using UnityEngine;

public class Example : MonoBehaviour
{
    public string m_name;
}

例えば、上記のようなコンポーネントを自作して、

using UnityEditor;

[CanEditMultipleObjects]
[CustomEditor( typeof( Example ) )]
public sealed class ExampleInspector : Editor
{
    public override void OnInspectorGUI()
    {
        var example = target as Example;

        using ( var scope = new EditorGUI.ChangeCheckScope() )
        {
            var name = EditorGUILayout.TextField( "Name", example.m_name );

            // 名前が入力されたら
            if ( scope.changed )
            {
                // 入力された名前を反映する
                example.m_name = name;
            }
        }
    }
}

自作したコンポーネントの Inspector を拡張するためのクラスを定義して
さらに、CanEditMultipleObjects 属性を適用して
複数のオブジェクトが選択されていても、
正しくエディタ拡張が表示されるようにしたとします

f:id:baba_s:20190501143247g:plain

しかし、これだけでは、複数のオブジェクトが選択された状態で
パラメータを変更しても、1つのオブジェクトにしかパラメータが反映されません

using System.Linq;
using UnityEditor;

[CanEditMultipleObjects]
[CustomEditor( typeof( Example ) )]
public sealed class ExampleInspector : Editor
{
    public override void OnInspectorGUI()
    {
        var example = target as Example;

        using ( var scope = new EditorGUI.ChangeCheckScope() )
        {
            var name = EditorGUILayout.TextField( "Name", example.m_name );

            // 名前が入力されたら
            if ( scope.changed )
            {
                // ★ 選択中のすべてのオブジェクトに反映する
                foreach ( var n in targets.OfType<Example>() )
                {
                    n.m_name = name;
                }
            }
        }
    }
}

選択中のすべてのオブジェクトにパラメータの変更を反映したい場合は
上記のコードのように targets 変数を使用する必要があります

f:id:baba_s:20190501143503g:plain

targets 変数を使用すると、
選択中のすべてのオブジェクトにパラメータの変更を反映できます

参考サイト様