MRが楽しい

MRやVRについて学習したことを書き残す

Inspectorビューのボタン操作で指定オブジェクト配下のオブジェクト状態を更新する

本日は Unity の小ネタ枠です。
Inspectorビューのボタン操作で指定オブジェクト配下のオブジェクト状態を更新する方法を記事にします。

Inspectorビューへのボタン追加

Inspector ビューにボタンを追加するには CustomEditor を利用します。
docs.unity3d.com

サンプルコード

今回は CustomEditor で追加したボタン押下時に、そのオブジェクトの配下を再帰的に走査してボタンのテキストをオブジェクト名と同じに更新するスクリプトを作成しました。
・ButtonObjectRefresh.cs

using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.MixedReality.Toolkit.UI;
using UnityEngine;

public class ButtonObjectRefresh : MonoBehaviour
{
    [ContextMenu("RefreshChildrenObjects")]
    public void RefreshChildrenObjects()
    {
        RecursiveCheckChildrenObjects(this.gameObject, (obj) =>
        {
            ButtonConfigHelper buttonHelper = obj.GetComponent<ButtonConfigHelper>();

            if (buttonHelper != null)
            {
                string text = obj.name;
                buttonHelper.MainLabelText = text;
                return true;
            }

            return false;
        });

    }

    #region "private"
    private bool RecursiveCheckChildrenObjects(GameObject a_TargetObject, Func<GameObject, bool> a_ExecuteMethod)
    {
        bool result = a_ExecuteMethod(a_TargetObject);

        foreach (Transform childTransform in a_TargetObject.transform)
        {
            result = result | RecursiveCheckChildrenObjects(childTransform.gameObject, a_ExecuteMethod);
        }

        return result;
    }
    #endregion
}

・ButtonObjectRefreshEditor.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;

using CUSTOMTYPE = ButtonObjectRefresh;

// 拡張するクラスを指定する
[CustomEditor(typeof(CUSTOMTYPE))]
public class ButtonObjectRefreshEditor : Editor
{
    // GUIの表示関数をオーバーライドする
    public override void OnInspectorGUI()
    {
        // 元のインスペクター部分を表示
        base.OnInspectorGUI();

        // targetを変換して対象スクリプトの参照を取得する
        CUSTOMTYPE targetScript = target as CUSTOMTYPE;

        // Editorを実行していないときのみ追加UIを表示する
        if (EditorApplication.isPlaying == false)
        {
            // public関数を実行するボタンの作成
            if (GUILayout.Button("RefreshChildrenObjectsの実行"))
            {
                targetScript.RefreshChildrenObjects();
            }
        }
    }
}
#endif

サンプルスクリプトを子オブジェクトにボタンを持つオブジェクトに設定します。

動作確認

ボタンを押下してボタンの更新関数を実行します。

以下の通り、全てのボタンオブジェクトのテキストがオブジェクト名と同じに更新されました。