// =============================================================================== // StickyNoteEditor - Custom Inspector & Scene Gizmo for U_StickyNote // // Creator: Scove // Last Updated: 2026-03-03 // Version: 2.0 (Ergonomic UI & Scene Rendering) // // Purpose: // Enhances the Unity Inspector and Scene View for the U_StickyNote component. // Makes level designing and leaving notes in the scene intuitive, readable, // and visually appealing. // // Key Features: // 1. Beautiful Scene Gizmos: Renders a colored background pad with // auto-contrasting text (black/white) for readability in any environment. // 2. Pin-Line Indicator: Draws a visual pin connecting the floating note // to its actual GameObject position. // 3. Ergonomic Inspector: Large text area for multi-line notes instead of // a cramped default single-line text field. // 4. Quick Color Presets: 1-click pastel color buttons (Yellow, Blue, Green, // Pink, White) for rapid and aesthetic note tagging. // // How to Use: // 1. Place this script in an 'Editor' folder. // 2. Attach your 'StickyNote' script to any GameObject in the scene. // 3. Select the GameObject to see the upgraded Inspector and Scene View note! // =============================================================================== using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace Editor { [CustomEditor(typeof(global::StickyNote))] public class StickyNoteEditor : UnityEditor.Editor { private SerializedProperty noteText; private SerializedProperty noteColor; private SerializedProperty showAlways; // Cache background texture for performance optimization private static Dictionary backgroundCache = new Dictionary(); private void OnEnable() { // Link properties from the original script noteText = serializedObject.FindProperty("noteText"); noteColor = serializedObject.FindProperty("noteColor"); showAlways = serializedObject.FindProperty("showAlways"); } public override void OnInspectorGUI() { serializedObject.Update(); // 1. Stylish Header EditorGUILayout.Space(5); GUIStyle headerStyle = new GUIStyle(EditorStyles.boldLabel) { fontSize = 14, alignment = TextAnchor.MiddleCenter }; EditorGUILayout.LabelField("📝 STICKY NOTE PANEL", headerStyle); EditorGUILayout.Space(5); // 2. Large & Convenient Text Input Area EditorGUILayout.LabelField("Note Content:", EditorStyles.boldLabel); GUIStyle textAreaStyle = new GUIStyle(EditorStyles.textArea) { wordWrap = true, fontSize = 12, padding = new RectOffset(8, 8, 8, 8) }; noteText.stringValue = EditorGUILayout.TextArea(noteText.stringValue, textAreaStyle, GUILayout.Height(80)); EditorGUILayout.Space(5); // 3. Quick Color Selection Buttons (Preset Colors - highly convenient) EditorGUILayout.LabelField("Quick Colors:", EditorStyles.boldLabel); GUILayout.BeginHorizontal(); DrawColorPresetButton("Yellow", new Color(1f, 0.92f, 0.53f)); // Pastel Yellow DrawColorPresetButton("Blue", new Color(0.68f, 0.85f, 0.9f)); // Pastel Blue DrawColorPresetButton("Green", new Color(0.67f, 0.88f, 0.69f)); // Pastel Green DrawColorPresetButton("Pink", new Color(1f, 0.71f, 0.76f)); // Pastel Pink DrawColorPresetButton("White", new Color(0.95f, 0.95f, 0.95f)); // Off-white GUILayout.EndHorizontal(); // Custom color picker EditorGUILayout.PropertyField(noteColor, new GUIContent("Custom Color")); EditorGUILayout.Space(5); // 4. Toggle Settings EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.PropertyField(showAlways, new GUIContent("📌 Show Always in Scene")); EditorGUILayout.EndVertical(); serializedObject.ApplyModifiedProperties(); } // Function to create a colored button private void DrawColorPresetButton(string label, Color color) { Color oldColor = GUI.backgroundColor; GUI.backgroundColor = color; if (GUILayout.Button(label, GUILayout.Height(25))) { noteColor.colorValue = color; } GUI.backgroundColor = oldColor; } // ========================================================================= // SCENE VIEW RENDERING - VISUAL NOTE INTERFACE // ========================================================================= [DrawGizmo(GizmoType.NonSelected | GizmoType.Selected | GizmoType.Active)] static void DrawGizmo(StickyNote note, GizmoType gizmoType) { if (!note.showAlways && (gizmoType & GizmoType.Selected) == 0) return; if (string.IsNullOrEmpty(note.noteText)) return; Vector3 basePos = note.transform.position; Vector3 labelPos = basePos + Vector3.up * 1.2f; // Height of the note board // 1. Draw the "Pin" and connecting line Gizmos.color = note.noteColor; Gizmos.DrawLine(basePos, labelPos); Gizmos.DrawSphere(basePos, 0.1f); // Pin base Gizmos.DrawSphere(labelPos, 0.05f); // Pin top // 2. Initialize Style for the Note Board GUIStyle noteStyle = new GUIStyle(GUI.skin.label); noteStyle.normal.background = GetBackgroundTexture(note.noteColor); // Calculate text color for readability (If dark background -> white text, light background -> black text) float luminance = (0.299f * note.noteColor.r) + (0.587f * note.noteColor.g) + (0.114f * note.noteColor.b); noteStyle.normal.textColor = luminance > 0.6f ? Color.black : Color.white; noteStyle.fontSize = 13; noteStyle.fontStyle = FontStyle.Bold; noteStyle.alignment = TextAnchor.MiddleCenter; noteStyle.padding = new RectOffset(10, 10, 8, 8); // Text distance to border (Padding) // 3. Draw Label with sharp background and padding Handles.Label(labelPos + Vector3.up * 0.2f, note.noteText, noteStyle); } // Function to automatically create colored background Texture (Cache to prevent lag) private static Texture2D GetBackgroundTexture(Color color) { // Make the color slightly transparent for a more professional look Color bgColor = new Color(color.r, color.g, color.b, 0.9f); if (!backgroundCache.TryGetValue(bgColor, out Texture2D tex) || tex == null) { tex = new Texture2D(1, 1); tex.SetPixel(0, 0, bgColor); tex.Apply(); backgroundCache[bgColor] = tex; } return tex; } } }