Add audio to dialogues
This commit is contained in:
@@ -11,33 +11,44 @@ namespace Dialogue.Editor
|
||||
{
|
||||
// Height constants
|
||||
private const float TypeSelectorHeight = 20f;
|
||||
private const float PropertySpacing = 2f;
|
||||
private const float PropertySpacing = 2f; // Reduced spacing for tighter layout
|
||||
private const float TextFieldHeight = 40f; // Taller for multi-line text
|
||||
private const float ImageFieldHeight = 18f;
|
||||
private const float AudioFieldHeight = 18f;
|
||||
private const float PreviewHeight = 64f;
|
||||
|
||||
// Track the last assigned sprite to detect changes
|
||||
private static Sprite lastAssignedSprite;
|
||||
private static string lastAssignedPropertyPath;
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
var contentTypeProperty = property.FindPropertyRelative("_contentType");
|
||||
var imageProperty = property.FindPropertyRelative("_image");
|
||||
|
||||
// Start with base height for type selector
|
||||
var height = TypeSelectorHeight + PropertySpacing;
|
||||
|
||||
// Add height based on content type
|
||||
if (contentTypeProperty.enumValueIndex == (int)DialogueContentType.Text)
|
||||
{
|
||||
height += TextFieldHeight;
|
||||
height += TextFieldHeight + PropertySpacing;
|
||||
}
|
||||
else // Image
|
||||
{
|
||||
height += ImageFieldHeight;
|
||||
height += ImageFieldHeight + PropertySpacing;
|
||||
|
||||
// Add preview height if an image is assigned
|
||||
var imageProperty = property.FindPropertyRelative("_image");
|
||||
// Add preview height if an image is assigned - make sure it's AFTER the image field
|
||||
// but BEFORE the audio field
|
||||
if (imageProperty.objectReferenceValue != null)
|
||||
{
|
||||
height += PropertySpacing + PreviewHeight;
|
||||
height += PreviewHeight + PropertySpacing;
|
||||
}
|
||||
}
|
||||
|
||||
// Add height for audio field (always displayed)
|
||||
height += AudioFieldHeight;
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
@@ -54,15 +65,58 @@ namespace Dialogue.Editor
|
||||
var contentTypeProperty = property.FindPropertyRelative("_contentType");
|
||||
var textProperty = property.FindPropertyRelative("_text");
|
||||
var imageProperty = property.FindPropertyRelative("_image");
|
||||
var audioProperty = property.FindPropertyRelative("_audio");
|
||||
|
||||
// Calculate rects
|
||||
var typeRect = new Rect(contentRect.x, contentRect.y, contentRect.width, TypeSelectorHeight);
|
||||
// Check for sprite changes and force repaint if needed
|
||||
var currentSprite = imageProperty.objectReferenceValue as Sprite;
|
||||
if (currentSprite != lastAssignedSprite && property.propertyPath == lastAssignedPropertyPath)
|
||||
{
|
||||
// Sprite changed, force a layout recalculation
|
||||
EditorUtility.SetDirty(property.serializedObject.targetObject);
|
||||
GUI.changed = true;
|
||||
}
|
||||
|
||||
// Track current y position as we add controls
|
||||
float currentY = contentRect.y;
|
||||
|
||||
// Calculate type rect
|
||||
var typeRect = new Rect(contentRect.x, currentY, contentRect.width, TypeSelectorHeight);
|
||||
currentY += TypeSelectorHeight + PropertySpacing;
|
||||
|
||||
// Calculate content field rect based on the content type
|
||||
var contentHeight = contentTypeProperty.enumValueIndex == (int)DialogueContentType.Text ?
|
||||
TextFieldHeight : ImageFieldHeight;
|
||||
|
||||
var contentFieldRect = new Rect(
|
||||
contentRect.x,
|
||||
contentRect.y + TypeSelectorHeight + PropertySpacing,
|
||||
currentY,
|
||||
contentRect.width,
|
||||
contentTypeProperty.enumValueIndex == (int)DialogueContentType.Text ? TextFieldHeight : ImageFieldHeight);
|
||||
contentHeight);
|
||||
|
||||
currentY += contentHeight + PropertySpacing;
|
||||
|
||||
// If we have an image and it's selected, calculate preview rect
|
||||
Rect previewRect = Rect.zero;
|
||||
if (contentTypeProperty.enumValueIndex == (int)DialogueContentType.Image &&
|
||||
imageProperty.objectReferenceValue != null)
|
||||
{
|
||||
previewRect = new Rect(
|
||||
contentRect.x,
|
||||
currentY,
|
||||
contentRect.width,
|
||||
PreviewHeight);
|
||||
|
||||
currentY += PreviewHeight + PropertySpacing;
|
||||
}
|
||||
|
||||
// Calculate audio field rect
|
||||
var audioFieldRect = new Rect(
|
||||
contentRect.x,
|
||||
currentY,
|
||||
contentRect.width,
|
||||
AudioFieldHeight);
|
||||
|
||||
// Now draw all the controls
|
||||
// Draw the content type dropdown
|
||||
EditorGUI.PropertyField(typeRect, contentTypeProperty, GUIContent.none);
|
||||
|
||||
@@ -78,8 +132,27 @@ namespace Dialogue.Editor
|
||||
}
|
||||
else // Image
|
||||
{
|
||||
// Store the sprite before drawing the field to detect changes
|
||||
var previousSprite = imageProperty.objectReferenceValue as Sprite;
|
||||
|
||||
// Draw the image field
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUI.PropertyField(contentFieldRect, imageProperty, GUIContent.none);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
// Image changed, store the property path so we can detect which property changed
|
||||
lastAssignedPropertyPath = property.propertyPath;
|
||||
lastAssignedSprite = imageProperty.objectReferenceValue as Sprite;
|
||||
|
||||
// Force an inspector update to recalculate layout
|
||||
EditorUtility.SetDirty(property.serializedObject.targetObject);
|
||||
// Mark the scene as dirty to ensure serialization and proper layout refresh
|
||||
if (!EditorApplication.isPlaying)
|
||||
{
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(
|
||||
UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene());
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a preview if an image is assigned
|
||||
if (imageProperty.objectReferenceValue != null)
|
||||
@@ -87,44 +160,58 @@ namespace Dialogue.Editor
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the audio field (always displayed regardless of content type)
|
||||
EditorGUI.PropertyField(audioFieldRect, audioProperty, new GUIContent("Audio"));
|
||||
|
||||
// Restore indent
|
||||
EditorGUI.indentLevel = indent;
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
private void DrawSpritePreview(Rect position, Sprite sprite)
|
||||
// Helper method to draw a sprite preview with preserved aspect ratio
|
||||
private void DrawSpritePreview(Rect rect, Sprite sprite)
|
||||
{
|
||||
if (sprite == null || sprite.texture == null) return;
|
||||
if (sprite == null || sprite.texture == null)
|
||||
return;
|
||||
|
||||
var texture = sprite.texture;
|
||||
var spriteRect = sprite.rect;
|
||||
var aspectRatio = spriteRect.width / spriteRect.height;
|
||||
|
||||
// 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;
|
||||
// Calculate preview rect while preserving aspect ratio within our fixed area
|
||||
Rect previewRect = rect;
|
||||
|
||||
// Center the preview
|
||||
Rect previewRect = new Rect(
|
||||
position.x + (position.width - targetWidth) * 0.5f,
|
||||
position.y + (position.height - targetHeight) * 0.5f,
|
||||
targetWidth,
|
||||
targetHeight
|
||||
);
|
||||
// Limit the display size to the allocated space while maintaining aspect ratio
|
||||
if (aspectRatio > 1f) // Wider than tall
|
||||
{
|
||||
previewRect.height = Mathf.Min(rect.width / aspectRatio, rect.height);
|
||||
previewRect.y += (rect.height - previewRect.height) * 0.5f;
|
||||
}
|
||||
else // Taller than wide or square
|
||||
{
|
||||
previewRect.width = Mathf.Min(rect.height * aspectRatio, rect.width);
|
||||
previewRect.x += (rect.width - previewRect.width) * 0.5f;
|
||||
}
|
||||
|
||||
// Draw the sprite preview
|
||||
EditorGUI.DrawPreviewTexture(previewRect, sprite.texture, null, ScaleMode.ScaleToFit);
|
||||
// Constrain the preview to the allocated space
|
||||
previewRect.height = Mathf.Min(previewRect.height, rect.height);
|
||||
previewRect.width = Mathf.Min(previewRect.width, rect.width);
|
||||
|
||||
// Draw a border around the preview
|
||||
GUI.Box(previewRect, GUIContent.none);
|
||||
// Draw preview with a dark background for better visibility
|
||||
EditorGUI.DrawRect(rect, new Color(0.1f, 0.1f, 0.1f, 1f));
|
||||
GUI.DrawTexture(previewRect, texture, ScaleMode.ScaleToFit);
|
||||
|
||||
// Draw sprite bounds
|
||||
EditorGUI.DrawRect(new Rect(previewRect.x, previewRect.y, previewRect.width, 1), Color.gray);
|
||||
EditorGUI.DrawRect(new Rect(previewRect.x, previewRect.y + previewRect.height - 1, previewRect.width, 1), Color.gray);
|
||||
EditorGUI.DrawRect(new Rect(previewRect.x, previewRect.y, 1, previewRect.height), Color.gray);
|
||||
EditorGUI.DrawRect(new Rect(previewRect.x + previewRect.width - 1, previewRect.y, 1, previewRect.height), Color.gray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user