内容将会持续更新,有错误的地方欢迎指正,谢谢!
拥有更好的学习体验 —— 不断努力,不断进步,不断探索 |
助力快速掌握 BoxCollider 编辑器扩展 为初学者节省宝贵的学习时间,避免困惑! |
前言:
之前在项目中想对一个对象做射线交互,然后给这个对象添加碰撞盒,发现这个对象下面还有很多子对
象,添加的碰撞盒不能完全包含这个对象及它下面的所有子对象,所以对BoxCollider进行了一个编辑器扩
展,实现当点击一个按钮时可以让这个BoxCollider包含该对象及其子对象。
TechX 教程效果:
文章目录
一、查找BoxCollider编辑器扩展类
1、安装.net反编译工具.NET Reflector
反编译工具.NET Reflector可以去它的官网进行下载。
网上也有很多破解教程,可以自行去百度进行搜索,对于大家来说也是比较简单的,这里就不再详细讲解。
安装好后是这样的:
我这里安装的是.NET Reflector11.1版本。
2、反编译UnityEditor.dll
打开.NET Reflector软件,选择UnityEditor.dll集合进行反编译
在搜索框中输入BoxCollider
进行搜索,可以看到有一个BoxColliderEditor
类,
查看右侧代码有CustomEditor(typeof(BoxCollider))
,我们知道CustomEditor类
为BoxCollider
的编辑器类。
二、创建编辑器扩展类BoxColliderExtendEditor
在Unity中创建一个编辑器类BoxColliderExtendEditor
,将这个类放到Editor文件夹中
通过反射(Reflection)获取到BoxCollider的编辑器类
private IEnumerator Init()
{
Type type = Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.BoxColliderEditor", false);
yield return new WaitUntil(() => type != null);
m_Editor = Editor.CreateEditor(target, type);
}
扩展对象及其所有子对象的边界框Bound
/// <summary>
/// 扩展边界
/// </summary>
public Bounds ExtentionBounds()
{
Vector3 center = Vector3.zero;
MeshRenderer[] renderers = Target.GetComponentsInChildren<MeshRenderer>();
for (int i = 0; i < renderers.Length; i++)
{
center += renderers[i].bounds.center;
}
center /= renderers.Length;
Bounds bounds = new Bounds(center, Vector3.zero);
for (int i = 0; i < renderers.Length; i++)
{
bounds.Encapsulate(renderers[i].bounds);
}
return bounds;
}
下面贴出完整的代码:
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Unity.EditorCoroutines.Editor;
using System.Collections;
namespace BCE
{
[CustomEditor(typeof(BoxCollider))]
public class BoxColliderExtendEditor:Editor
{
private Editor m_Editor;
private bool isFlip;
private void OnEnable()
{
EditorCoroutineUtility.StartCoroutineOwnerless(Init());
}
private IEnumerator Init()
{
Type type = Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.BoxColliderEditor", false);
yield return new WaitUntil(() => type != null);
m_Editor = Editor.CreateEditor(target, type);
}
private BoxCollider Target { get { return (BoxCollider)target; } }
public override void OnInspectorGUI()
{
if (m_Editor == null) return;
m_Editor.OnInspectorGUI();
GUILayout.Space(10);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Flip");
isFlip = EditorGUILayout.ToggleLeft("",isFlip);
EditorGUILayout.EndHorizontal();
GUI.color = new Color(0, 1, 0, 0.5f);
GUILayout.Space(10);
if (GUILayout.Button("Adaptive Size"))
{
Bounds bounds = ExtentionBounds();
Vector3 center = bounds.center - Target.transform.position;
if (isFlip)
{
Target.center = new Vector3(center.z, center.y, -center.x);
Target.size = new Vector3(bounds.size.z, bounds.size.y, bounds.size.x);
}
else
{
Target.center = center;
Target.size = bounds.size;
}
}
GUI.color = Color.white;
}
/// <summary>
/// 扩展边界
/// </summary>
public Bounds ExtentionBounds()
{
Vector3 center = Vector3.zero;
MeshRenderer[] renderers = Target.GetComponentsInChildren<MeshRenderer>();
for (int i = 0; i < renderers.Length; i++)
{
center += renderers[i].bounds.center;
}
center /= renderers.Length;
Bounds bounds = new Bounds(center, Vector3.zero);
for (int i = 0; i < renderers.Length; i++)
{
bounds.Encapsulate(renderers[i].bounds);
}
return bounds;
}
}
}
每一次跌倒都是一次成长 每一次努力都是一次进步 |
感谢您阅读本篇博客!希望这篇内容对您有所帮助。如果您有任何问题或意见,或者想要了解更多关于本主题的信息,欢迎在评论区留言与我交流。我会非常乐意与大家讨论和分享更多有趣的内容。
如果您喜欢本博客,请点赞和分享给更多的朋友,让更多人受益。同时,您也可以关注我的博客,以便及时获取最新的更新和文章。
在未来的写作中,我将继续努力,分享更多有趣、实用的内容。再次感谢大家的支持和鼓励,期待与您在下一篇博客再见!