夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

Unityであるオブジェクトのすべての子オブジェクトの持つコライダーをオンオフにする

本日はUnity枠です。

Unityのアプリケーションでコライダーは時に思わぬバグを生む可能性があり、必要がないコライダーは削除すべきですが、デバッグやのちの開発のためにディアクティブにしておくということもよく使う手法です。

今回はエディタ拡張を使用してあるゲームオブジェクトの子オブジェクトからすべてのコライダーのオンオフを一括管理する機能を紹介します。

〇コード

今回は先にコードを紹介します。

折り畳み

using System.Collections.Generic;
using NUnit.Framework.Constraints;
using UnityEngine;
using UnityEditor;


[ExecuteInEditMode]
public class ColliderManager : MonoBehaviour
{
#if UNITY_EDITOR
   [SerializeField] private List<Collider> colliders = new List<Collider>();
   [SerializeField] private bool _isOptimizedForHoloLens = false;
   [SerializeField] private bool _isDefaltColliderStatus = true;
    private void Reset()
    {
        GetCollidersInChildren(transform, colliders);
    }

    private void GetCollidersInChildren(Transform parent, List<Collider> colliders)
    {
        foreach (Transform child in parent)
        {
            Collider collider = child.GetComponent<Collider>();
            if (collider != null)
            {
                if (collider.gameObject.name == "コライダー対象外にしたいオブジェクト名")
                {
                    Debug.Log("コライダー削除対象外があります。");
                }
                else
                {
                    colliders.Add(collider);   
                }
            }
            GetCollidersInChildren(child, colliders);
        }
    }
    public void SetCollidersEnabled(bool enabled)
    {
        _isDefaltColliderStatus = enabled;
        _isOptimizedForHoloLens = !enabled;
        foreach (Collider collider in colliders)
        {
            collider.enabled = enabled;
        }
    }

    [CustomEditor(typeof(ColliderManager))]
    public class ColliderManagerEditor : Editor
    {
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            
            ColliderManager colliderManager = (ColliderManager)target;
            
            if (GUILayout.Button("Enable Colliders"))
            {
                colliderManager.SetCollidersEnabled(true);
            }
            if (GUILayout.Button("Disable Colliders(for HoloLensBuild)"))
            {
                colliderManager.SetCollidersEnabled(false);
            }
        }
    }
    #endif
}

[ExecuteInEditMode]アトリビュートをつけることでUnityエディタ上で関数が実行できるようにしています。

エディタ拡張によりボタンを表示させるColliderManagerEditorクラスと実際の機能を定義しているColliderManager 2つのクラスが存在しています。

〇使い方

子オブジェクトのコライダーをオンオフ一括管理したいオブジェクトの親オブジェクトにアタッチします。

今回はIs Optimized For HoloLensIs Default Collider Statusの二つのチェックボックスを用意していますが、こちらはステータス表示用に使用しています。

具体的には今回HoloLens用に最適化したかったのでビルド時にDisable Colliders(for HoloLensBuild)をクリックすることで子オブジェクトのコライダーが全オフになります。

対象のコライダーはCollidersの配列に一覧表示されます。

もし子オブジェクトにignoreしたいオブジェクトがある場合はコード内のGetCollidersInChildrenから if (collider.gameObject.name == "コライダー対象外にしたいオブジェクト名")に任意のオブジェクト名を指定します。

 private void GetCollidersInChildren(Transform parent, List<Collider> colliders)
    {
        foreach (Transform child in parent)
        {
            Collider collider = child.GetComponent<Collider>();
            if (collider != null)
            {
                if (collider.gameObject.name == "コライダー対象外にしたいオブジェクト名")
                {
                    Debug.Log("コライダー削除対象外があります。");
                }
                else
                {
                    colliders.Add(collider);   
                }
            }
            GetCollidersInChildren(child, colliders);
        }
    }

以上で一括コライダーをオンオフする機能の紹介でした。