当前位置:网站首页>Unity自动生成阻挡Collider的GameObject工具
Unity自动生成阻挡Collider的GameObject工具
2022-08-04 05:25:00 【丁小未】
前言
场景中会有碰撞阻挡,或者触发器,一般是美术或者策划配置,策划一般是直接配置collider,但为了调试方便,需要显示对应的mesh方便查看防止的位置是否正确,我们可以写个工具来控制生成mesh和删除mesh方便调试使用。
思路
一般就是几种内置的collider,meshcollider、boxcollider、capsulecollider、spherecollider等,我们判断出对应的collider,然后创建unity内置的一些GameObject即可,meshcollider只需要实例化collider的mesh即可。
效果
代码
#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
更多精品教程
边栏推荐
- Dynamic programming of the division of numbers
- C专家编程 第5章 对链接的思考 5.4 警惕Interpositioning
- word 公式编辑器 键入技巧 | 写数学作业必备速查表
- MySQL数据库面试题总结(2022最新版)
- 12. Paging plugin
- MySql数据恢复方法个人总结
- canal实现mysql数据同步
- idea设置识别.sql文件类型以及其他文件类型
- 7.13 Day20----MYSQL
- DataTable uses Linq for grouping and summarization, and converts the Linq result set into DataTable
猜你喜欢
随机推荐
自动化测试的成本高效果差,那么自动化测试的意义在哪呢?
MySql数据恢复方法个人总结
8.03 Day34---BaseMapper查询语句用法
The 2022 PMP exam has been delayed, should we be happy or worried?
你以为border-radius只是圆角吗?【各种角度】
7.13 Day20----MYSQL
【问题解决】同一机器上Flask部署TensorRT报错记录
The Road to Ad Monetization for Uni-app Mini Program Apps: Full Screen Video Ads
MySQL date functions
C专家编程 第5章 对链接的思考 5.3 函数库链接的5个特殊秘密
Programming hodgepodge (4)
文献管理工具 | Zotero
力扣题解8/3
[Cocos 3.5.2]开启模型合批
word 公式编辑器 键入技巧 | 写数学作业必备速查表
Redis common interview questions
px、em、rem的区别
嵌入式系统驱动初级【3】——字符设备驱动基础中_IO模型
MySQL日期函数
What are the steps for how to develop a mall system APP?