前言

场景中会有碰撞阻挡,或者触发器,一般是美术或者策划配置,策划一般是直接配置collider,但为了调试方便,需要显示对应的mesh方便查看防止的位置是否正确,我们可以写个工具来控制生成mesh和删除mesh方便调试使用。

思路

一般就是几种内置的collider,meshcollider、boxcollider、capsulecollider、spherecollider等,我们判断出对应的collider,然后创建unity内置的一些GameObject即可,meshcollider只需要实例化collider的mesh即可。

效果

Unity自动生成阻挡Collider的GameObject工具_Unity自动生成阻挡


Unity自动生成阻挡Collider的GameObject工具_List_02


Unity自动生成阻挡Collider的GameObject工具_System_03

代码

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

using Sirenix.Utilities.Editor;
using Sirenix.OdinInspector;
using System;

public class ColliderMeshGenerateTool : MonoBehaviour
{
    bool show = false;
    List<GameObject> mColliderObjCache = new List<GameObject>();
    List<GameObject> mGameObjects = new List<GameObject>();
    [ShowInInspector]
    public bool Show
    {
        get
        {
            return show;
        }
        set
        {
            ChangeState(value);
            show = value;
        }
    }

    void Start()
    {
        mGameObjects = GetAllSceneObjectsWithInactive();
    }

    private void ChangeState(bool isShow)
    {
        if (isShow)
        {
            foreach (var obj in mGameObjects)
            {
                if (obj.GetComponent<MeshRenderer>() == null)
                    AnalyzeCollider(obj);
            }
        }
        else
        {
            for (int i = mColliderObjCache.Count - 1; i >= 0; i--)
            {
                GameObject.DestroyImmediate(mColliderObjCache[i]);
            }
            mColliderObjCache.Clear();
        }
    }

    private void AnalyzeCollider(GameObject obj)
    {
        var collider = obj.GetComponent<Collider>();
        if (collider == null)
        {
            Debug.LogError("不存在Collider");
            return;
        }
        Type type = collider.GetType();
        GameObject tempObj = null;
        if (type == typeof(SphereCollider))
        {
            tempObj = CreatePrimitiveGameObject(obj.transform, PrimitiveType.Sphere);
            var sphereCollider = obj.GetComponent<SphereCollider>();
            tempObj.transform.localScale = sphereCollider.radius * Vector3.one * 2;
        }
        else if (type == typeof(BoxCollider))
        {
            tempObj = CreatePrimitiveGameObject(obj.transform, PrimitiveType.Cube);
            var boxCollider = obj.GetComponent<BoxCollider>();
            tempObj.transform.localScale = boxCollider.size;
        }
        else if (type == typeof(MeshCollider))
        {
            tempObj = CreateGameObject(obj.transform, "MeshGameObject");
            tempObj.AddComponent<MeshRenderer>();
            var filter = tempObj.AddComponent<MeshFilter>();
            var meshCollider = obj.GetComponent<MeshCollider>();
            filter.mesh = meshCollider.sharedMesh;
        }
        else if (type == typeof(CapsuleCollider))
        {
            tempObj = CreatePrimitiveGameObject(obj.transform, PrimitiveType.Capsule);
            var capsuleCollider = obj.GetComponent<CapsuleCollider>();
            var doubleRadius = capsuleCollider.radius * 2;
            var tempScaleY = capsuleCollider.height < capsuleCollider.radius * 2 ? capsuleCollider.radius : capsuleCollider.height / 2;
            tempObj.transform.localScale = new Vector3(doubleRadius, tempScaleY, doubleRadius);
        }
        if (tempObj != null)
            mColliderObjCache.Add(tempObj);
    }

    private GameObject CreatePrimitiveGameObject(Transform parent, PrimitiveType type = PrimitiveType.Cube)
    {
        var obj = GameObject.CreatePrimitive(type);
        obj.transform.parent = parent;
        ResetTransformData(obj);
        return obj;
    }

    private GameObject CreateGameObject(Transform parent, string name)
    {
        var obj = new GameObject(name);
        obj.transform.parent = parent;
        ResetTransformData(obj);
        return obj;
    }

    private void ResetTransformData(GameObject obj)
    {
        obj.transform.localPosition = Vector3.zero;
        obj.transform.localRotation = Quaternion.Euler(Vector3.zero);
        obj.transform.localScale = Vector3.one;
    }


    /// <summary>
    /// Select All ActiveInHierarchy GameObject in Hierarchy
    /// </summary>
    /// <returns></returns>
    private List<GameObject> GetAllSceneObjectsWithInactive()
    {
        var allTransforms = Resources.FindObjectsOfTypeAll(typeof(Transform));
        var previousSelection = Selection.objects;
        Selection.objects = allTransforms.Cast<Transform>()
            .Where(x => x != null)
            .Select(x => x.gameObject)
            .Where(x => x != null && x.activeInHierarchy)
            .Where(x => x.GetComponent<Collider>() != null)
            .Cast<UnityEngine.Object>().ToArray();
        var selectedTransforms = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);
        Selection.objects = previousSelection;
        return selectedTransforms.Select(tr => tr.gameObject).ToList();
    }
}
#endif

http://dingxiaowei.cn/