Created
September 25, 2021 09:49
-
-
Save longde123/5283aa26afb03bff86b5ee1b742c0669 to your computer and use it in GitHub Desktop.
Draw gizmo for colliders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using UnityEngine; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
#endif | |
namespace MyBox | |
{ | |
public class ColliderGizmo : MonoBehaviour | |
{ | |
#if UNITY_EDITOR | |
public Presets Preset; | |
public Color CustomWireColor; | |
public Color CustomFillColor; | |
public Color CustomCenterColor; | |
public float Alpha = 1.0f; | |
public Color WireColor = new Color(.6f, .6f, 1f, .5f); | |
public Color FillColor = new Color(.6f, .7f, 1f, .1f); | |
public Color CenterColor = new Color(.6f, .7f, 1f, .7f); | |
public bool DrawFill = true; | |
public bool DrawWire = true; | |
public bool DrawCenter; | |
/// <summary> | |
/// The radius of the center marker on your collider(s) | |
/// </summary> | |
public float CenterMarkerRadius = 1.0f; | |
public bool IncludeChildColliders; | |
private List<EdgeCollider2D> _edgeColliders2D; | |
private List<BoxCollider2D> _boxColliders2D; | |
private List<CircleCollider2D> _circleColliders2D; | |
private List<BoxCollider> _boxColliders; | |
private List<SphereCollider> _sphereColliders; | |
private readonly HashSet<Transform> _withColliders = new HashSet<Transform>(); | |
private Color _wireGizmoColor; | |
private Color _fillGizmoColor; | |
private Color _centerGizmoColor; | |
private bool _initialized; | |
private void OnDrawGizmos() | |
{ | |
if (!enabled) return; | |
if (!_initialized) Refresh(); | |
DrawColliders(); | |
} | |
#region Refresh | |
public void Refresh() | |
{ | |
_initialized = true; | |
_wireGizmoColor = new Color(WireColor.r, WireColor.g, WireColor.b, WireColor.a * Alpha); | |
_fillGizmoColor = new Color(FillColor.r, FillColor.g, FillColor.b, FillColor.a * Alpha); | |
_centerGizmoColor = new Color(CenterColor.r, CenterColor.g, CenterColor.b, CenterColor.a * Alpha); | |
_withColliders.Clear(); | |
if (_edgeColliders2D != null) _edgeColliders2D.Clear(); | |
if (_boxColliders2D != null) _boxColliders2D.Clear(); | |
if (_circleColliders2D != null) _circleColliders2D.Clear(); | |
if (_boxColliders != null) _boxColliders.Clear(); | |
if (_sphereColliders != null) _sphereColliders.Clear(); | |
Collider2D[] colliders2d = IncludeChildColliders ? gameObject.GetComponentsInChildren<Collider2D>() : gameObject.GetComponents<Collider2D>(); | |
Collider[] colliders = IncludeChildColliders ? gameObject.GetComponentsInChildren<Collider>() : gameObject.GetComponents<Collider>(); | |
for (var i = 0; i < colliders2d.Length; i++) | |
{ | |
var c = colliders2d[i]; | |
var box2d = c as BoxCollider2D; | |
if (box2d != null) | |
{ | |
if (_boxColliders2D == null) _boxColliders2D = new List<BoxCollider2D>(); | |
_boxColliders2D.Add(box2d); | |
_withColliders.Add(box2d.transform); | |
continue; | |
} | |
var edge = c as EdgeCollider2D; | |
if (edge != null) | |
{ | |
if (_edgeColliders2D == null) _edgeColliders2D = new List<EdgeCollider2D>(); | |
_edgeColliders2D.Add(edge); | |
_withColliders.Add(edge.transform); | |
continue; | |
} | |
var circle2d = c as CircleCollider2D; | |
if (circle2d != null) | |
{ | |
if (_circleColliders2D == null) _circleColliders2D = new List<CircleCollider2D>(); | |
_circleColliders2D.Add(circle2d); | |
_withColliders.Add(circle2d.transform); | |
} | |
} | |
for (var i = 0; i < colliders.Length; i++) | |
{ | |
var c = colliders[i]; | |
var box = c as BoxCollider; | |
if (box != null) | |
{ | |
if (_boxColliders == null) _boxColliders = new List<BoxCollider>(); | |
_boxColliders.Add(box); | |
_withColliders.Add(box.transform); | |
continue; | |
} | |
var sphere = c as SphereCollider; | |
if (sphere != null) | |
{ | |
if (_sphereColliders == null) _sphereColliders = new List<SphereCollider>(); | |
_sphereColliders.Add(sphere); | |
_withColliders.Add(sphere.transform); | |
} | |
} | |
} | |
#endregion | |
#region Drawers | |
private void DrawEdgeCollider2D(EdgeCollider2D coll) | |
{ | |
var target = coll.transform; | |
var lossyScale = target.lossyScale; | |
var position = target.position; | |
Gizmos.color = WireColor; | |
Vector3 previous = Vector2.zero; | |
bool first = true; | |
for (int i = 0; i < coll.points.Length; i++) | |
{ | |
var collPoint = coll.points[i]; | |
Vector3 pos = new Vector3(collPoint.x * lossyScale.x, collPoint.y * lossyScale.y, 0); | |
Vector3 rotated = target.rotation * pos; | |
if (first) first = false; | |
else | |
{ | |
Gizmos.color = _wireGizmoColor; | |
Gizmos.DrawLine(position + previous, position + rotated); | |
} | |
previous = rotated; | |
DrawColliderGizmo(target.position + rotated, .05f); | |
} | |
} | |
private void DrawBoxCollider2D(BoxCollider2D coll) | |
{ | |
var target = coll.transform; | |
Gizmos.matrix = Matrix4x4.TRS(target.position, target.rotation, target.lossyScale); | |
DrawColliderGizmo(coll.offset, coll.size); | |
Gizmos.matrix = Matrix4x4.identity; | |
} | |
private void DrawBoxCollider(BoxCollider coll) | |
{ | |
var target = coll.transform; | |
Gizmos.matrix = Matrix4x4.TRS(target.position, target.rotation, target.lossyScale); | |
DrawColliderGizmo(coll.center, coll.size); | |
Gizmos.matrix = Matrix4x4.identity; | |
} | |
private void DrawCircleCollider2D(CircleCollider2D coll) | |
{ | |
var target = coll.transform; | |
var offset = coll.offset; | |
var scale = target.lossyScale; | |
DrawColliderGizmo(target.position + new Vector3(offset.x, offset.y, 0.0f), coll.radius * Mathf.Max(scale.x, scale.y)); | |
} | |
private void DrawSphereCollider(SphereCollider coll) | |
{ | |
var target = coll.transform; | |
var scale = target.lossyScale; | |
var center = coll.center; | |
var max = Mathf.Max(scale.x, Mathf.Max(scale.y, scale.z)); // to not use Mathf.Max version with params[] | |
DrawColliderGizmo(target.position + new Vector3(center.x, center.y, 0.0f), coll.radius * max); | |
} | |
private void DrawColliders() | |
{ | |
if (DrawCenter) | |
{ | |
Gizmos.color = _centerGizmoColor; | |
foreach (var withCollider in _withColliders) | |
{ | |
Gizmos.DrawSphere(withCollider.position, CenterMarkerRadius); | |
} | |
} | |
Gizmos.color = new Color(WireColor.r, WireColor.g, WireColor.b, WireColor.a * Alpha); | |
Gizmos.color = new Color(FillColor.r, FillColor.g, FillColor.b, FillColor.a * Alpha); | |
if (!DrawWire && !DrawFill) return; | |
if (_edgeColliders2D != null) | |
{ | |
foreach (var edge in _edgeColliders2D) | |
{ | |
if (edge == null) continue; | |
DrawEdgeCollider2D(edge); | |
} | |
} | |
if (_boxColliders2D != null) | |
{ | |
foreach (var box in _boxColliders2D) | |
{ | |
if (box == null) continue; | |
DrawBoxCollider2D(box); | |
} | |
} | |
if (_circleColliders2D != null) | |
{ | |
foreach (var circle in _circleColliders2D) | |
{ | |
if (circle == null) continue; | |
DrawCircleCollider2D(circle); | |
} | |
} | |
if (_boxColliders != null) | |
{ | |
foreach (var box in _boxColliders) | |
{ | |
if (box == null) continue; | |
DrawBoxCollider(box); | |
} | |
} | |
if (_sphereColliders != null) | |
{ | |
foreach (var sphere in _sphereColliders) | |
{ | |
if (sphere == null) continue; | |
DrawSphereCollider(sphere); | |
} | |
} | |
} | |
private void DrawColliderGizmo(Vector3 position, Vector3 size) | |
{ | |
if (DrawWire) | |
{ | |
Gizmos.color = _wireGizmoColor; | |
Gizmos.DrawWireCube(position, size); | |
} | |
if (DrawFill) | |
{ | |
Gizmos.color = _fillGizmoColor; | |
Gizmos.DrawCube(position, size); | |
} | |
} | |
private void DrawColliderGizmo(Vector3 position, float radius) | |
{ | |
if (DrawWire) | |
{ | |
Gizmos.color = _wireGizmoColor; | |
Gizmos.DrawWireSphere(position, radius); | |
} | |
if (DrawFill) | |
{ | |
Gizmos.color = _fillGizmoColor; | |
Gizmos.DrawSphere(position, radius); | |
} | |
} | |
#endregion | |
#region Change Preset | |
public enum Presets | |
{ | |
Custom, | |
Red, | |
Blue, | |
Green, | |
Purple, | |
Yellow, | |
Aqua, | |
White, | |
Lilac, | |
DirtySand | |
} | |
public void ChangePreset(Presets preset) | |
{ | |
Preset = preset; | |
switch (Preset) | |
{ | |
case Presets.Red: | |
WireColor = new Color32(143, 0, 21, 202); | |
FillColor = new Color32(218, 0, 0, 37); | |
CenterColor = new Color32(135, 36, 36, 172); | |
break; | |
case Presets.Blue: | |
WireColor = new Color32(0, 116, 214, 202); | |
FillColor = new Color32(0, 110, 218, 37); | |
CenterColor = new Color32(57, 160, 221, 172); | |
break; | |
case Presets.Green: | |
WireColor = new Color32(153, 255, 187, 128); | |
FillColor = new Color32(153, 255, 187, 62); | |
CenterColor = new Color32(153, 255, 187, 172); | |
break; | |
case Presets.Purple: | |
WireColor = new Color32(138, 138, 234, 128); | |
FillColor = new Color32(173, 178, 255, 26); | |
CenterColor = new Color32(153, 178, 255, 172); | |
break; | |
case Presets.Yellow: | |
WireColor = new Color32(255, 231, 35, 128); | |
FillColor = new Color32(255, 252, 153, 100); | |
CenterColor = new Color32(255, 242, 84, 172); | |
break; | |
case Presets.DirtySand: | |
WireColor = new Color32(255, 170, 0, 60); | |
FillColor = new Color32(180, 160, 80, 175); | |
CenterColor = new Color32(255, 242, 84, 172); | |
break; | |
case Presets.Aqua: | |
WireColor = new Color32(255, 255, 255, 120); | |
FillColor = new Color32(0, 230, 255, 140); | |
CenterColor = new Color32(255, 255, 255, 120); | |
break; | |
case Presets.White: | |
WireColor = new Color32(255, 255, 255, 130); | |
FillColor = new Color32(255, 255, 255, 130); | |
CenterColor = new Color32(255, 255, 255, 130); | |
break; | |
case Presets.Lilac: | |
WireColor = new Color32(255, 255, 255, 255); | |
FillColor = new Color32(160, 190, 255, 140); | |
CenterColor = new Color32(255, 255, 255, 130); | |
break; | |
case Presets.Custom: | |
WireColor = CustomWireColor; | |
FillColor = CustomFillColor; | |
CenterColor = CustomCenterColor; | |
break; | |
} | |
Refresh(); | |
} | |
#endregion | |
#endif | |
} | |
#if UNITY_EDITOR | |
namespace MyBox.Internal | |
{ | |
[CustomEditor(typeof(ColliderGizmo)), CanEditMultipleObjects] | |
public class ColliderGizmoEditor : Editor | |
{ | |
private SerializedProperty _enabledProperty; | |
private SerializedProperty _alphaProperty; | |
private SerializedProperty _drawWireProperty; | |
private SerializedProperty _wireColorProperty; | |
private SerializedProperty _drawFillProperty; | |
private SerializedProperty _fillColorProperty; | |
private SerializedProperty _drawCenterProperty; | |
private SerializedProperty _centerColorProperty; | |
private SerializedProperty _centerRadiusProperty; | |
private SerializedProperty _includeChilds; | |
private ColliderGizmo _target; | |
private int _collidersCount; | |
private void OnEnable() | |
{ | |
_target = target as ColliderGizmo; | |
_enabledProperty = serializedObject.FindProperty("m_Enabled"); | |
_alphaProperty = serializedObject.FindProperty("Alpha"); | |
_drawWireProperty = serializedObject.FindProperty("DrawWire"); | |
_wireColorProperty = serializedObject.FindProperty("WireColor"); | |
_drawFillProperty = serializedObject.FindProperty("DrawFill"); | |
_fillColorProperty = serializedObject.FindProperty("FillColor"); | |
_drawCenterProperty = serializedObject.FindProperty("DrawCenter"); | |
_centerColorProperty = serializedObject.FindProperty("CenterColor"); | |
_centerRadiusProperty = serializedObject.FindProperty("CenterMarkerRadius"); | |
_includeChilds = serializedObject.FindProperty("IncludeChildColliders"); | |
_collidersCount = CollidersCount(); | |
} | |
public override void OnInspectorGUI() | |
{ | |
Undo.RecordObject(_target, "CG_State"); | |
EditorGUILayout.PropertyField(_enabledProperty); | |
EditorGUI.BeginChangeCheck(); | |
_target.Preset = (ColliderGizmo.Presets) EditorGUILayout.EnumPopup("Color Preset", _target.Preset); | |
if (EditorGUI.EndChangeCheck()) | |
{ | |
foreach (var singleTarget in targets) | |
{ | |
var gizmo = (ColliderGizmo) singleTarget; | |
gizmo.ChangePreset(_target.Preset); | |
EditorUtility.SetDirty(gizmo); | |
} | |
} | |
_alphaProperty.floatValue = EditorGUILayout.Slider("Overall Transparency", _alphaProperty.floatValue, 0, 1); | |
EditorGUI.BeginChangeCheck(); | |
using (new EditorGUILayout.HorizontalScope()) | |
{ | |
EditorGUILayout.PropertyField(_drawWireProperty); | |
if (_drawWireProperty.boolValue) EditorGUILayout.PropertyField(_wireColorProperty, new GUIContent("")); | |
} | |
using (new EditorGUILayout.HorizontalScope()) | |
{ | |
EditorGUILayout.PropertyField(_drawFillProperty); | |
if (_drawFillProperty.boolValue) EditorGUILayout.PropertyField(_fillColorProperty, new GUIContent("")); | |
} | |
using (new EditorGUILayout.HorizontalScope()) | |
{ | |
EditorGUILayout.PropertyField(_drawCenterProperty); | |
if (_drawCenterProperty.boolValue) | |
{ | |
EditorGUILayout.PropertyField(_centerColorProperty, GUIContent.none); | |
EditorGUILayout.PropertyField(_centerRadiusProperty); | |
} | |
} | |
if (EditorGUI.EndChangeCheck()) | |
{ | |
var presetProp = serializedObject.FindProperty("Preset"); | |
var customWireColor = serializedObject.FindProperty("CustomWireColor"); | |
var customFillColor = serializedObject.FindProperty("CustomFillColor"); | |
var customCenterColor = serializedObject.FindProperty("CustomCenterColor"); | |
presetProp.enumValueIndex = (int) ColliderGizmo.Presets.Custom; | |
customWireColor.colorValue = _wireColorProperty.colorValue; | |
customFillColor.colorValue = _fillColorProperty.colorValue; | |
customCenterColor.colorValue = _centerColorProperty.colorValue; | |
} | |
EditorGUILayout.PropertyField(_includeChilds); | |
int collidersCountCheck = CollidersCount(); | |
bool collidersCountChanged = collidersCountCheck != _collidersCount; | |
_collidersCount = collidersCountCheck; | |
if (GUI.changed || collidersCountChanged) | |
{ | |
serializedObject.ApplyModifiedProperties(); | |
EditorUtility.SetDirty(_target); | |
_target.Refresh(); | |
} | |
} | |
private int CollidersCount() | |
{ | |
if (_includeChilds.boolValue) | |
{ | |
return _target.gameObject.GetComponentsInChildren<Collider>().Length + | |
_target.gameObject.GetComponentsInChildren<Collider2D>().Length; | |
} | |
return _target.gameObject.GetComponents<Collider>().Length + | |
_target.gameObject.GetComponents<Collider2D>().Length; | |
} | |
} | |
} | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment