Created
October 26, 2019 20:15
-
-
Save orangy/8f5626fad791df28cf5cba8c4c5aa28d to your computer and use it in GitHub Desktop.
Improve transform inspector to show and edit bounds
This file contains hidden or 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 UnityEditor; | |
using UnityEngine; | |
using System; | |
using System.Reflection; | |
using Component = UnityEngine.Component; | |
namespace Editor.Customizations | |
{ | |
[CustomEditor(typeof(Transform))] | |
public class TransformCustomizedEditor : UnityEditor.Editor | |
{ | |
private UnityEditor.Editor myDefaultEditor; | |
private Transform myTransform; | |
private static bool ourLockAspect = true; | |
private static GUIContent ourLockedContent; | |
private static GUIContent ourUnlockedContent; | |
private static GUIStyle ourLockContentStyle; | |
void OnEnable() | |
{ | |
if (ourLockedContent == null) | |
{ | |
ourLockedContent = new GUIContent() | |
{ | |
text = "Bounds", | |
tooltip = "Aspect Ratio is locked, click to unlock", | |
image = EditorGUIUtility.IconContent("InspectorLock", "").image | |
}; | |
ourUnlockedContent = new GUIContent() | |
{ | |
text = "Bounds", | |
tooltip = "Aspect Ratio is unlocked, click to lock", | |
image = EditorGUIUtility.IconContent("d_InspectorLock", "").image | |
}; | |
} | |
// When this inspector is created, also create the built-in inspector | |
myDefaultEditor = CreateEditor(targets, Type.GetType("UnityEditor.TransformInspector, UnityEditor")); | |
myTransform = target as Transform; | |
} | |
void OnDisable() | |
{ | |
// When OnDisable is called, the default editor we created should be destroyed to avoid memory leakage. | |
// Also, make sure to call any required methods like OnDisable | |
var disableMethod = myDefaultEditor.GetType().GetMethod("OnDisable", | |
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); | |
if (disableMethod != null) | |
disableMethod.Invoke(myDefaultEditor, null); | |
DestroyImmediate(myDefaultEditor); | |
} | |
public override void OnInspectorGUI() | |
{ | |
myDefaultEditor.OnInspectorGUI(); | |
if (TryGetBounds(myTransform, out var bounds)) | |
EditorBounds(bounds); | |
} | |
private static bool TryGetBounds(Component transform, out Bounds bounds) | |
{ | |
var gameObject = transform.gameObject; | |
if (gameObject.TryGetComponent<Collider>(out var collider)) | |
{ | |
bounds = collider.bounds; | |
return true; | |
} | |
if (gameObject.TryGetComponent<Renderer>(out var renderer)) | |
{ | |
bounds = renderer.bounds; | |
return true; | |
} | |
bounds = default; | |
return false; | |
} | |
[DrawGizmo(GizmoType.Selected)] | |
static void DrawGizmosSelected(Transform transform, GizmoType gizmoType) | |
{ | |
if (TryGetBounds(transform, out var bounds)) | |
Gizmos.DrawWireCube(bounds.center, bounds.extents * 2); | |
} | |
private void EditorBounds(Bounds bounds) | |
{ | |
EditorGUILayout.Space(); | |
var lockedContent = ourLockAspect ? ourLockedContent : ourUnlockedContent; | |
if (ourLockContentStyle == null) | |
{ | |
// This cannot be done in OnEnable, because skin is not loaded yet :( | |
ourLockContentStyle = new GUIStyle(EditorStyles.boldLabel) | |
{ | |
fontStyle = FontStyle.Bold | |
}; | |
} | |
ourLockAspect = GUILayout.Toggle(ourLockAspect, lockedContent, ourLockContentStyle); | |
var originalSize = bounds.extents * 2; | |
var newSize = EditorGUILayout.Vector3Field("Size", originalSize); | |
var localScale = myTransform.localScale; | |
// fullSize = originalSize / originalScale | |
// newScale = newSize / fullSize | |
if (!Mathf.Approximately(newSize.x, originalSize.x)) | |
{ | |
var aspect = newSize.x / originalSize.x; | |
if (ourLockAspect) | |
localScale *= aspect; | |
else | |
localScale.x *= aspect; | |
} | |
if (!Mathf.Approximately(newSize.y, originalSize.y)) | |
{ | |
var aspect = newSize.y / originalSize.y; | |
if (ourLockAspect) | |
localScale *= aspect; | |
else | |
localScale.y *= aspect; | |
} | |
if (!Mathf.Approximately(newSize.z, originalSize.z)) | |
{ | |
var aspect = newSize.z / originalSize.z; | |
if (ourLockAspect) | |
localScale *= aspect; | |
else | |
localScale.z *= aspect; | |
} | |
myTransform.localScale = localScale; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment