When I’m trying to line up colliders on my prefabs and world geometry, it is a little hard to be certain exactly where the limits are. This is especially true with colliders that are much larger than the area I’m working with.
It would be super handy if there was an option to make colliders have a semi-transparent color. So if I’m lining up a box collider with my world geometry. instead of having just the green wireframe where I have to keep spinning my camera around and then guessing how close it is, the box collider could be drawn as a semi-transparent box, and then I could see clearly where the edge of the box is; I could easily recognize what geometry is sticking past the collider and what is still behind it.
Yes it is unbelievable that Unity still don’t have an option to have a solid visualization of colliders.
You can easily write editor tools for this:
#if UNITY_EDITOR
public class ColliderGizmoDrawers
{
[DrawGizmo(GizmoType.Selected | GizmoType.Active, typeof(BoxCollider))]
static void DrawGizmoForMyScript(BoxCollider col, GizmoType gizmoType)
{
Gizmo.matrix = col.transform.localToWorldMatrix;
Vector3 size = col.size;
Gizmo.DrawCube(Vector3.zero, size);
Gizmo.matrix = Matrix4x4.identity;
}
}
#endif
Not 100% correct but not bothered to do so in notepad. This will draw box colliders as a solid box when selected.
Okay I was curious as to how ‘nice’ I could make this, as if it were an actual Unity tool. Turns out there’s lots of cool Editor API stuff to make it intuitive:
(Couldn’t be assed making a gif).
This is using the Overlays API. Relevant code below:
// the visual element used in the overlay toolbar
[EditorToolbarElement(SolidCollidersToolbarToggle.id, typeof(SceneView))]
internal sealed class SolidCollidersToolbarToggle : EditorToolbarToggle
{
public const string id = "Colliders/DrawSolidColliders";
public SolidCollidersToolbarToggle() : base()
{
text = "Draw Solid Colliders";
tooltip = "Toggles whether colliders should be drawn as solid or as wireframe.";
icon = (Texture2D)EditorGUIUtility.Load("d_BoxCollider Icon");
this.SetValueWithoutNotify(LBGEditorPreferences.DrawSolidColliders);
this.RegisterValueChangedCallback<bool>(HandleToggleValue);
}
private void HandleToggleValue(ChangeEvent<bool> value)
{
LBGEditorPreferences.DrawSolidColliders = value.newValue;
}
}
[Overlay(typeof(SceneView), "Collider Tools")]
internal sealed class ColliderToolbar : ToolbarOverlay
{
public ColliderToolbar() : base(SolidCollidersToolbarToggle.id) { }
}
internal static class ColliderGizmosDrawer
{
[DrawGizmo(GizmoType.Active | GizmoType.Selected, typeof(BoxCollider))]
public static void HandleDrawBoxColliderGizmo(BoxCollider collider, GizmoType gizmoType)
{
if (gizmoType.HasFlag(GizmoType.NotInSelectionHierarchy))
{
return;
}
bool solid = LBGEditorPreferences.DrawSolidColliders;
Color c = Color.green;
c.a = 0.5f;
DrawGizmosUtilities.DrawBoxColliderGizmos(collider, c, solid);
}
}
public static class DrawGizmosUtilities
{
public static void DrawBoxColliderGizmos(BoxCollider box, Color color, bool drawSolid)
{
Gizmos.matrix = box.transform.localToWorldMatrix;
Gizmos.color = color;
Vector3 offset = box.center;
Vector3 size = box.size;
if (drawSolid)
{
Gizmos.DrawCube(offset, size);
}
else
{
Gizmos.DrawWireCube(offset, size);
}
Gizmos.matrix = Matrix4x4.identity;
}
}
Definitely can be expanded upon (which I will be doing in due time). I just used EditorPrefs to store the value (handled by LBGEditorPreferences
)
2 Likes
Ruuds
July 11, 2024, 3:43pm
5
spiney199:
Okay I was curious as to how ‘nice’ I could make this, as if it were an actual Unity tool. Turns out there’s lots of cool Editor API stuff to make it intuitive:
(Couldn’t be assed making a gif).
This is using the Overlays API. Relevant code below:
// the visual element used in the overlay toolbar
[EditorToolbarElement(SolidCollidersToolbarToggle.id, typeof(SceneView))]
internal sealed class SolidCollidersToolbarToggle : EditorToolbarToggle
{
public const string id = "Colliders/DrawSolidColliders";
public SolidCollidersToolbarToggle() : base()
{
text = "Draw Solid Colliders";
tooltip = "Toggles whether colliders should be drawn as solid or as wireframe.";
icon = (Texture2D)EditorGUIUtility.Load("d_BoxCollider Icon");
this.SetValueWithoutNotify(LBGEditorPreferences.DrawSolidColliders);
this.RegisterValueChangedCallback<bool>(HandleToggleValue);
}
private void HandleToggleValue(ChangeEvent<bool> value)
{
LBGEditorPreferences.DrawSolidColliders = value.newValue;
}
}
[Overlay(typeof(SceneView), "Collider Tools")]
internal sealed class ColliderToolbar : ToolbarOverlay
{
public ColliderToolbar() : base(SolidCollidersToolbarToggle.id) { }
}
internal static class ColliderGizmosDrawer
{
[DrawGizmo(GizmoType.Active | GizmoType.Selected, typeof(BoxCollider))]
public static void HandleDrawBoxColliderGizmo(BoxCollider collider, GizmoType gizmoType)
{
if (gizmoType.HasFlag(GizmoType.NotInSelectionHierarchy))
{
return;
}
bool solid = LBGEditorPreferences.DrawSolidColliders;
Color c = Color.green;
c.a = 0.5f;
DrawGizmosUtilities.DrawBoxColliderGizmos(collider, c, solid);
}
}
public static class DrawGizmosUtilities
{
public static void DrawBoxColliderGizmos(BoxCollider box, Color color, bool drawSolid)
{
Gizmos.matrix = box.transform.localToWorldMatrix;
Gizmos.color = color;
Vector3 offset = box.center;
Vector3 size = box.size;
if (drawSolid)
{
Gizmos.DrawCube(offset, size);
}
else
{
Gizmos.DrawWireCube(offset, size);
}
Gizmos.matrix = Matrix4x4.identity;
}
}
Definitely can be expanded upon (which I will be doing in due time). I just used EditorPrefs to store the value (handled by LBGEditorPreferences
)
Hi, came across this thread looking for the same thing, I am not great at editor scripting, how do I implement this? “The name ‘LBGEditorPreferences’ does not exist in the current context”
Ruuds:
Hi, came across this thread looking for the same thing, I am not great at editor scripting, how do I implement this? “The name ‘LBGEditorPreferences’ does not exist in the current context”
Yes because it’s my own class. You would have to implement something yourself.
A better way to handle persistent editor preference I’ve discovered since that post is with the ScriptableSingleton class: https://docs.unity3d.com/6000.0/Documentation/ScriptReference/ScriptableSingleton_1.html