MRが楽しい

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

MeshとColliderを無効化してオブジェクトを無効化にする

本日は Unity の小ネタ枠です。
MeshとColliderを無効化してオブジェクトを非表示にする方法を記事にします。

オブジェクトの無効化

シーン内の特定オブジェクトを無効化する場合、SetActive から false を設定することでオブジェクトを無効化できます。
・ObjectActive.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectActive : MonoBehaviour
{
    /// <summary>
    /// オブジェクトを無効化する
    /// </summary>
    [ContextMenu("DisableObject")]
    public void DisableObject()
    {
        this.gameObject.SetActive(false);
    }

    /// <summary>
    /// オブジェクトを有効化する
    /// </summary>
    [ContextMenu("EnableObject")]
    public void EnableObject()
    {
        this.gameObject.SetActive(true);
    }
}


ただし、この方法を用いる場合オブジェクトに付属するコンポーネント群も無効化されるため、エラーハンドリングを正しく行っていないスクリプトで予期しないエラーが発生することがあります。

MeshとColliderを無効化する

そこで以下のように見た目を構成する Mesh コンポーネントとアタリ判定を構成する Collider コンポーネントを無効化することでオブジェクトを疑似的に無効化します。
この方法であれば付属するコンポーネント群は無効化せず、疑似的にオブジェクトを無効化できます。
・MeshAndColliderActive.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MeshAndColliderActive : MonoBehaviour
{
    /// <summary>
    /// 子を含むオブジェクトのMeshとColliderを無効化する
    /// </summary>
    [ContextMenu("DisableMeshAndCollider")]
    public void DisableMeshAndCollider()
    {
        RecursiveCheckMeshAndCollider(this.gameObject, false);
    }

    /// <summary>
    /// 子を含むオブジェクトのMeshとColliderを有効化する
    /// </summary>
    [ContextMenu("EnableMeshAndCollider")]
    public void EnableMeshAndCollider()
    {
        RecursiveCheckMeshAndCollider(this.gameObject, true);
    }

    private void RecursiveCheckMeshAndCollider(GameObject a_TargetObject, bool a_OnOff)
    {
        MeshRenderer mesh = a_TargetObject.GetComponent<MeshRenderer>();
        if (mesh != null) mesh.enabled = a_OnOff;

        Collider collider = a_TargetObject.GetComponent<Collider>();
        if (collider != null) collider.enabled = a_OnOff;

        foreach (Transform child in a_TargetObject.transform)
        {
            RecursiveCheckMeshAndCollider(child.gameObject, a_OnOff);
        }
    }
}