using UnityEditor; using UnityEngine; namespace Dialogue.Editor { /// /// Custom property drawer for DialogueContent that displays either text or image fields based on content type /// [CustomPropertyDrawer(typeof(DialogueContent))] public class DialogueContentDrawer : PropertyDrawer { // Height constants private const float TypeSelectorHeight = 20f; private const float PropertySpacing = 2f; private const float TextFieldHeight = 40f; // Taller for multi-line text private const float ImageFieldHeight = 18f; private const float PreviewHeight = 64f; public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { var contentTypeProperty = property.FindPropertyRelative("_contentType"); var height = TypeSelectorHeight + PropertySpacing; // Add height based on content type if (contentTypeProperty.enumValueIndex == (int)DialogueContentType.Text) { height += TextFieldHeight; } else // Image { height += ImageFieldHeight; // Add preview height if an image is assigned var imageProperty = property.FindPropertyRelative("_image"); if (imageProperty.objectReferenceValue != null) { height += PropertySpacing + PreviewHeight; } } return height; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(position, label, property); // Create a property field and indent it var contentRect = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); var indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; // Get properties var contentTypeProperty = property.FindPropertyRelative("_contentType"); var textProperty = property.FindPropertyRelative("_text"); var imageProperty = property.FindPropertyRelative("_image"); // Calculate rects var typeRect = new Rect(contentRect.x, contentRect.y, contentRect.width, TypeSelectorHeight); var contentFieldRect = new Rect( contentRect.x, contentRect.y + TypeSelectorHeight + PropertySpacing, contentRect.width, contentTypeProperty.enumValueIndex == (int)DialogueContentType.Text ? TextFieldHeight : ImageFieldHeight); // Draw the content type dropdown EditorGUI.PropertyField(typeRect, contentTypeProperty, GUIContent.none); // Draw the appropriate field based on content type if (contentTypeProperty.enumValueIndex == (int)DialogueContentType.Text) { // Create a custom style with word wrap enabled GUIStyle wordWrapStyle = new GUIStyle(EditorStyles.textArea); wordWrapStyle.wordWrap = true; // Text field with word wrap for multi-line input textProperty.stringValue = EditorGUI.TextArea(contentFieldRect, textProperty.stringValue, wordWrapStyle); } else // Image { // Draw the image field EditorGUI.PropertyField(contentFieldRect, imageProperty, GUIContent.none); // Draw a preview if an image is assigned if (imageProperty.objectReferenceValue != null) { var sprite = imageProperty.objectReferenceValue as Sprite; if (sprite != null) { var previewRect = new Rect( contentRect.x, contentFieldRect.y + contentFieldRect.height + PropertySpacing, contentRect.width, PreviewHeight); // Draw the preview with preserved aspect ratio DrawSpritePreview(previewRect, sprite); } } } EditorGUI.indentLevel = indent; EditorGUI.EndProperty(); } private void DrawSpritePreview(Rect position, Sprite sprite) { if (sprite == null || sprite.texture == null) return; // Calculate aspect-preserved rect float aspectRatio = sprite.rect.width / sprite.rect.height; float targetWidth = Mathf.Min(position.width, position.height * aspectRatio); float targetHeight = targetWidth / aspectRatio; // Center the preview Rect previewRect = new Rect( position.x + (position.width - targetWidth) * 0.5f, position.y + (position.height - targetHeight) * 0.5f, targetWidth, targetHeight ); // Draw the sprite preview EditorGUI.DrawPreviewTexture(previewRect, sprite.texture, null, ScaleMode.ScaleToFit); // Draw a border around the preview GUI.Box(previewRect, GUIContent.none); } } }