You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
7.5 KiB
C#

1 year ago
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Timeline;
using UnityEngine;
using UnityEngine.Timeline;
using UnityEngine.UIElements;
#if !UNITY_2020_2_OR_NEWER
using L10n = UnityEditor.Timeline.L10n;
#endif
/// <summary>
/// Store the editor preferences for Timeline.
/// </summary>
[FilePath("TimelinePreferences.asset", FilePathAttribute.Location.PreferencesFolder)]
public class TimelinePreferences : ScriptableSingleton<TimelinePreferences>
{
/// <summary>
/// The time unit used by the Timeline Editor when displaying time values.
/// </summary>
[SerializeField]
public TimeFormat timeFormat;
/// <summary>
/// Define the time unit for the timeline window.
/// true : frame unit.
/// false : timecode unit.
/// </summary>
[NonSerialized, Obsolete("timeUnitInFrame is deprecated. Use timeFormat instead", false)]
public bool timeUnitInFrame;
/// <summary>
/// Draw the waveforms for all audio clips.
/// </summary>
[SerializeField]
public bool showAudioWaveform = true;
/// <summary>
/// Allow the users to hear audio while scrubbing on audio clip.
/// </summary>
[SerializeField]
bool m_AudioScrubbing;
/// <summary>
/// Enables audio scrubbing when moving the playhead.
/// </summary>
public bool audioScrubbing
{
get { return m_AudioScrubbing; }
set
{
if (m_AudioScrubbing != value)
{
m_AudioScrubbing = value;
TimelinePlayable.muteAudioScrubbing = !value;
TimelineEditor.Refresh(RefreshReason.ContentsModified);
}
}
}
/// <summary>
/// Enable Snap to Frame to manipulate clips and align them on frames.
/// </summary>
[SerializeField]
public bool snapToFrame = true;
#if TIMELINE_FRAMEACCURATE
[SerializeField] bool m_PlaybackLockedToFrame;
#endif
/// <summary>
/// Enable Timelines to be evaluated on frame during editor preview.
/// </summary>
public bool playbackLockedToFrame
{
get
{
#if TIMELINE_FRAMEACCURATE
return m_PlaybackLockedToFrame;
#else
Debug.LogWarning($"PlaybackLockedToFrame is not available for this Unity version");
return false;
#endif
}
set
{
#if TIMELINE_FRAMEACCURATE
m_PlaybackLockedToFrame = value;
TimelineEditor.RefreshPreviewPlay();
#else
Debug.LogWarning($"PlaybackLockedToFrame is not available for this Unity version");
#endif
}
}
/// <summary>
/// Enable the ability to snap clips on the edge of another clip.
/// </summary>
[SerializeField]
public bool edgeSnap = true;
/// <summary>
/// Behavior of the timeline window during playback.
/// </summary>
[SerializeField]
public PlaybackScrollMode playbackScrollMode = PlaybackScrollMode.None;
void OnDisable()
{
Save();
}
/// <summary>
/// Save the timeline preferences settings file.
/// </summary>
public void Save()
{
Save(true);
}
internal SerializedObject GetSerializedObject()
{
return new SerializedObject(this);
}
}
class TimelinePreferencesProvider : SettingsProvider
{
SerializedObject m_SerializedObject;
SerializedProperty m_ShowAudioWaveform;
SerializedProperty m_TimeFormat;
SerializedProperty m_SnapToFrame;
SerializedProperty m_EdgeSnap;
SerializedProperty m_PlaybackScrollMode;
SerializedProperty m_PlaybackLockedToFrame;
internal class Styles
{
public static readonly GUIContent TimeUnitLabel = L10n.TextContent("Time Unit", "Define the time unit for the timeline window (Frames, Timecode or Seconds).");
public static readonly GUIContent ShowAudioWaveformLabel = L10n.TextContent("Show Audio Waveforms", "Draw the waveforms for all audio clips.");
public static readonly GUIContent AudioScrubbingLabel = L10n.TextContent("Allow Audio Scrubbing", "Allow the users to hear audio while scrubbing on audio clip.");
public static readonly GUIContent SnapToFrameLabel = L10n.TextContent("Snap To Frame", "Enable Snap to Frame to manipulate clips and align them on frames.");
public static readonly GUIContent EdgeSnapLabel = L10n.TextContent("Edge Snap", "Enable the ability to snap clips on the edge of another clip.");
public static readonly GUIContent PlaybackScrollModeLabel = L10n.TextContent("Playback Scrolling Mode", "Define scrolling behavior during playback.");
public static readonly GUIContent EditorSettingLabel = L10n.TextContent("Timeline Editor Settings", "");
#if TIMELINE_FRAMEACCURATE
public static readonly GUIContent PlaybackLockedToFrame = L10n.TextContent("Playback Locked To Frame", "Enable Frame Accurate Preview.");
#endif
}
public TimelinePreferencesProvider(string path, SettingsScope scopes, IEnumerable<string> keywords = null)
: base(path, scopes, keywords)
{
}
public override void OnActivate(string searchContext, VisualElement rootElement)
{
TimelinePreferences.instance.Save();
m_SerializedObject = TimelinePreferences.instance.GetSerializedObject();
m_ShowAudioWaveform = m_SerializedObject.FindProperty("showAudioWaveform");
m_TimeFormat = m_SerializedObject.FindProperty("timeFormat");
m_SnapToFrame = m_SerializedObject.FindProperty("snapToFrame");
m_EdgeSnap = m_SerializedObject.FindProperty("edgeSnap");
m_PlaybackScrollMode = m_SerializedObject.FindProperty("playbackScrollMode");
#if TIMELINE_FRAMEACCURATE
m_PlaybackLockedToFrame = m_SerializedObject.FindProperty("m_PlaybackLockedToFrame");
#endif
}
public override void OnGUI(string searchContext)
{
m_SerializedObject.Update();
EditorGUI.BeginChangeCheck();
using (new SettingsWindow.GUIScope())
{
EditorGUILayout.LabelField(Styles.EditorSettingLabel, EditorStyles.boldLabel);
m_TimeFormat.enumValueIndex = EditorGUILayout.Popup(Styles.TimeUnitLabel, m_TimeFormat.enumValueIndex, m_TimeFormat.enumDisplayNames);
m_PlaybackScrollMode.enumValueIndex = EditorGUILayout.Popup(Styles.PlaybackScrollModeLabel, m_PlaybackScrollMode.enumValueIndex, m_PlaybackScrollMode.enumNames);
m_ShowAudioWaveform.boolValue = EditorGUILayout.Toggle(Styles.ShowAudioWaveformLabel, m_ShowAudioWaveform.boolValue);
TimelinePreferences.instance.audioScrubbing = EditorGUILayout.Toggle(Styles.AudioScrubbingLabel, TimelinePreferences.instance.audioScrubbing);
m_SnapToFrame.boolValue = EditorGUILayout.Toggle(Styles.SnapToFrameLabel, m_SnapToFrame.boolValue);
m_EdgeSnap.boolValue = EditorGUILayout.Toggle(Styles.EdgeSnapLabel, m_EdgeSnap.boolValue);
#if TIMELINE_FRAMEACCURATE
m_PlaybackLockedToFrame.boolValue = EditorGUILayout.Toggle(Styles.PlaybackLockedToFrame, m_PlaybackLockedToFrame.boolValue);
#endif
}
if (EditorGUI.EndChangeCheck())
{
m_SerializedObject.ApplyModifiedProperties();
TimelinePreferences.instance.Save();
TimelineEditor.Refresh(RefreshReason.WindowNeedsRedraw);
TimelineEditor.RefreshPreviewPlay();
}
}
[SettingsProvider]
public static SettingsProvider CreateTimelineProjectSettingProvider()
{
var provider = new TimelinePreferencesProvider("Preferences/Timeline", SettingsScope.User, GetSearchKeywordsFromGUIContentProperties<Styles>());
return provider;
}
}