Add VideoClipPlaylist component for sequential gapless clip playback
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>
This commit is contained in:
1 parent
ff01e07fa1
commit
36ce4a66df
4 files changed
+412
No files matched your search
@@ -0,0 +1,58 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7623ddbca00a62a4c8718ae46341b87a
|
||||
Reference in new issue
Block a user