Plays a list of items (clip + percentage range) on a VideoPlayer. Double-buffers via a second player (auto-created child incl. AudioSource copy) and drives the screen texture through a MaterialPropertyBlock, flipping only once the next player delivers frames - no black/freeze gap. Editor drawer renders each item as clip row + min-max percent range slider. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
59 lines
2.6 KiB
C#
59 lines
2.6 KiB
C#
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// Draws a <see cref="VideoClipPlaylist.Item"/> as two lines: the clip field and a
|
|
/// percent min-max slider (stored normalized 0..1) selecting the played portion.
|
|
/// </summary>
|
|
[CustomPropertyDrawer(typeof(VideoClipPlaylist.Item))]
|
|
public class VideoClipPlaylistItemDrawer : PropertyDrawer
|
|
{
|
|
private const float PercentFieldWidth = 44f;
|
|
private const float Gap = 4f;
|
|
|
|
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
|
=> EditorGUIUtility.singleLineHeight * 2f + EditorGUIUtility.standardVerticalSpacing;
|
|
|
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
|
{
|
|
SerializedProperty clipProp = property.FindPropertyRelative(nameof(VideoClipPlaylist.Item.clip));
|
|
SerializedProperty rangeProp = property.FindPropertyRelative(nameof(VideoClipPlaylist.Item.range));
|
|
|
|
EditorGUI.BeginProperty(position, label, property);
|
|
|
|
float line = EditorGUIUtility.singleLineHeight;
|
|
var clipRect = new Rect(position.x, position.y, position.width, line);
|
|
EditorGUI.PropertyField(clipRect, clipProp, label);
|
|
|
|
var rowRect = new Rect(position.x, clipRect.yMax + EditorGUIUtility.standardVerticalSpacing,
|
|
position.width, line);
|
|
Rect rangeRect = EditorGUI.PrefixLabel(rowRect, new GUIContent("Range (%)",
|
|
"Played portion of the clip in percent (start/end)."));
|
|
|
|
Vector2 range = rangeProp.vector2Value;
|
|
float min = Mathf.Round(range.x * 1000f) / 10f;
|
|
float max = Mathf.Round(range.y * 1000f) / 10f;
|
|
|
|
var minRect = new Rect(rangeRect.x, rangeRect.y, PercentFieldWidth, line);
|
|
var maxRect = new Rect(rangeRect.xMax - PercentFieldWidth, rangeRect.y, PercentFieldWidth, line);
|
|
var sliderRect = new Rect(minRect.xMax + Gap, rangeRect.y,
|
|
Mathf.Max(0f, rangeRect.width - 2f * (PercentFieldWidth + Gap)), line);
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
int indent = EditorGUI.indentLevel;
|
|
EditorGUI.indentLevel = 0; // fields inside the row must not re-indent
|
|
min = EditorGUI.FloatField(minRect, min);
|
|
EditorGUI.MinMaxSlider(sliderRect, ref min, ref max, 0f, 100f);
|
|
max = EditorGUI.FloatField(maxRect, max);
|
|
EditorGUI.indentLevel = indent;
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
min = Mathf.Clamp(min, 0f, 100f);
|
|
max = Mathf.Clamp(max, min, 100f);
|
|
rangeProp.vector2Value = new Vector2(min / 100f, max / 100f);
|
|
}
|
|
|
|
EditorGUI.EndProperty();
|
|
}
|
|
}
|