168 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			168 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System; | ||
|  | using System.Globalization; | ||
|  | using System.Linq; | ||
|  | using System.Text; | ||
|  | using JetBrains.Annotations; | ||
|  | using UnityEditor; | ||
|  | using UnityEditor.Timeline; | ||
|  | using UnityEngine.Playables; | ||
|  | #if !UNITY_2020_2_OR_NEWER | ||
|  | using L10n = UnityEditor.Timeline.L10n; | ||
|  | #endif | ||
|  | 
 | ||
|  | namespace UnityEngine.Timeline | ||
|  | { | ||
|  |     [CustomEditor(typeof(AudioTrack))] | ||
|  |     [CanEditMultipleObjects] | ||
|  |     class AudioTrackInspector : TrackAssetInspector | ||
|  |     { | ||
|  |         [UsedImplicitly] // Also used by tests | ||
|  |         internal static class Styles | ||
|  |         { | ||
|  |             public const string VolumeControl = "AudioTrackInspector.volume"; | ||
|  |             public const string StereoPanControl = "AudioTrackInspector.stereoPan"; | ||
|  |             public const string SpatialBlendControl = "AudioTrackInspector.spatialBlend"; | ||
|  | 
 | ||
|  |             const string k_Indent = "    "; | ||
|  |             public const string valuesFormatter = "0.###"; | ||
|  |             public const string mixInfoSectionSeparator = "\n\n"; | ||
|  |             public static string mixedPropertiesInfo = L10n.Tr("The final {3} is {0}\n") + | ||
|  |                 L10n.Tr("Calculated from:\n") + | ||
|  |                 k_Indent + L10n.Tr("Track: {1}\n") + | ||
|  |                 k_Indent + L10n.Tr("AudioSource: {2}"); | ||
|  |         } | ||
|  | 
 | ||
|  |         static StringBuilder s_MixInfoBuilder = new StringBuilder(); | ||
|  | 
 | ||
|  |         SerializedProperty m_VolumeProperty; | ||
|  |         SerializedProperty m_StereoPanProperty; | ||
|  |         SerializedProperty m_SpatialBlendProperty; | ||
|  |         PlayableDirector m_Director; | ||
|  | 
 | ||
|  |         public override void OnEnable() | ||
|  |         { | ||
|  |             base.OnEnable(); | ||
|  | 
 | ||
|  |             if (((AudioTrack)target).timelineAsset == TimelineEditor.inspectedAsset) | ||
|  |                 m_Director = TimelineEditor.inspectedDirector; | ||
|  | 
 | ||
|  |             m_VolumeProperty = serializedObject.FindProperty("m_TrackProperties.volume"); | ||
|  |             m_StereoPanProperty = serializedObject.FindProperty("m_TrackProperties.stereoPan"); | ||
|  |             m_SpatialBlendProperty = serializedObject.FindProperty("m_TrackProperties.spatialBlend"); | ||
|  |         } | ||
|  | 
 | ||
|  |         protected override void DrawTrackProperties() | ||
|  |         { | ||
|  |             // Volume | ||
|  |             GUI.SetNextControlName(Styles.VolumeControl); | ||
|  |             EditorGUILayout.Slider(m_VolumeProperty, 0.0f, 1.0f, AudioSourceInspector.Styles.volumeLabel); | ||
|  |             EditorGUILayout.Space(); | ||
|  | 
 | ||
|  |             // Stereo Pan | ||
|  |             GUI.SetNextControlName(Styles.StereoPanControl); | ||
|  |             EditorGUIUtility.sliderLabels.SetLabels(AudioSourceInspector.Styles.panLeftLabel, AudioSourceInspector.Styles.panRightLabel); | ||
|  |             EditorGUILayout.Slider(m_StereoPanProperty, -1.0f, 1.0f, AudioSourceInspector.Styles.panStereoLabel); | ||
|  |             EditorGUIUtility.sliderLabels.SetLabels(null, null); | ||
|  |             EditorGUILayout.Space(); | ||
|  | 
 | ||
|  |             // Spatial Blend | ||
|  |             using (new EditorGUI.DisabledScope(ShouldDisableSpatialBlend())) | ||
|  |             { | ||
|  |                 GUI.SetNextControlName(Styles.SpatialBlendControl); | ||
|  |                 EditorGUIUtility.sliderLabels.SetLabels(AudioSourceInspector.Styles.spatialLeftLabel, AudioSourceInspector.Styles.spatialRightLabel); | ||
|  |                 EditorGUILayout.Slider(m_SpatialBlendProperty, 0.0f, 1.0f, AudioSourceInspector.Styles.spatialBlendLabel); | ||
|  |                 EditorGUIUtility.sliderLabels.SetLabels(null, null); | ||
|  |             } | ||
|  | 
 | ||
|  |             DrawMixInfoSection(); | ||
|  |         } | ||
|  | 
 | ||
|  |         void DrawMixInfoSection() | ||
|  |         { | ||
|  |             if (m_Director == null || targets.Length > 1) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             var binding = m_Director.GetGenericBinding(target) as AudioSource; | ||
|  |             if (binding == null) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             var audioSourceVolume = binding.volume; | ||
|  |             var audioSourcePan = binding.panStereo; | ||
|  |             var audioSourceBlend = binding.spatialBlend; | ||
|  | 
 | ||
|  |             var trackVolume = m_VolumeProperty.floatValue; | ||
|  |             var trackPan = m_StereoPanProperty.floatValue; | ||
|  |             var trackBlend = m_SpatialBlendProperty.floatValue; | ||
|  | 
 | ||
|  |             // Skip sections when result is obvious | ||
|  | 
 | ||
|  |             var skipVolumeInfo = Math.Abs(audioSourceVolume) < float.Epsilon && Math.Abs(trackVolume) < float.Epsilon ||            // All muted | ||
|  |                 Math.Abs(audioSourceVolume - 1) < float.Epsilon && Math.Abs(trackVolume - 1) < float.Epsilon;                       // All max volume | ||
|  | 
 | ||
|  |             var skipPanInfo = Math.Abs(audioSourcePan) < float.Epsilon && Math.Abs(trackPan) < float.Epsilon ||                     // All centered | ||
|  |                 Math.Abs(audioSourcePan - 1) < float.Epsilon && Math.Abs(trackPan - 1) < float.Epsilon ||                           // All right | ||
|  |                 Math.Abs(audioSourcePan - (-1.0f)) < float.Epsilon && Math.Abs(trackPan - (-1.0f)) < float.Epsilon;                 // All left | ||
|  | 
 | ||
|  |             var skipBlendInfo = Math.Abs(audioSourceBlend) < float.Epsilon && Math.Abs(trackBlend) < float.Epsilon ||               // All 2D | ||
|  |                 Math.Abs(audioSourceBlend - 1) < float.Epsilon && Math.Abs(trackBlend - 1) < float.Epsilon;                         // All 3D | ||
|  | 
 | ||
|  |             if (skipVolumeInfo && skipPanInfo && skipBlendInfo) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             s_MixInfoBuilder.Length = 0; | ||
|  | 
 | ||
|  |             if (!skipVolumeInfo) | ||
|  |                 s_MixInfoBuilder.AppendFormat( | ||
|  |                     Styles.mixedPropertiesInfo, | ||
|  |                     (audioSourceVolume * trackVolume).ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture), | ||
|  |                     trackVolume.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture), | ||
|  |                     audioSourceVolume.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture), | ||
|  |                     AudioSourceInspector.Styles.volumeLabel.text); | ||
|  | 
 | ||
|  |             if (!skipVolumeInfo && !skipPanInfo) | ||
|  |                 s_MixInfoBuilder.Append(Styles.mixInfoSectionSeparator); | ||
|  | 
 | ||
|  |             if (!skipPanInfo) | ||
|  |                 s_MixInfoBuilder.AppendFormat( | ||
|  |                     Styles.mixedPropertiesInfo, | ||
|  |                     Mathf.Clamp(audioSourcePan + trackPan, -1.0f, 1.0f).ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture), | ||
|  |                     trackPan.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture), | ||
|  |                     audioSourcePan.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture), | ||
|  |                     AudioSourceInspector.Styles.panStereoLabel.text); | ||
|  | 
 | ||
|  |             if ((!skipVolumeInfo || !skipPanInfo) && !skipBlendInfo) | ||
|  |                 s_MixInfoBuilder.Append(Styles.mixInfoSectionSeparator); | ||
|  | 
 | ||
|  |             if (!skipBlendInfo) | ||
|  |                 s_MixInfoBuilder.AppendFormat( | ||
|  |                     Styles.mixedPropertiesInfo, | ||
|  |                     Mathf.Clamp01(audioSourceBlend + trackBlend).ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture), | ||
|  |                     trackBlend.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture), | ||
|  |                     audioSourceBlend.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture), | ||
|  |                     AudioSourceInspector.Styles.spatialBlendLabel.text); | ||
|  | 
 | ||
|  |             EditorGUILayout.Space(); | ||
|  |             EditorGUILayout.HelpBox(new GUIContent(s_MixInfoBuilder.ToString())); | ||
|  |         } | ||
|  | 
 | ||
|  |         protected override void ApplyChanges() | ||
|  |         { | ||
|  |             var track = (AudioTrack)target; | ||
|  | 
 | ||
|  |             if (TimelineEditor.inspectedAsset != track.timelineAsset || TimelineEditor.inspectedDirector == null) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             if (TimelineEditor.inspectedDirector.state == PlayState.Playing) | ||
|  |                 track.LiveLink(); | ||
|  |             else | ||
|  |                 TimelineEditor.Refresh(RefreshReason.ContentsModified); | ||
|  |         } | ||
|  | 
 | ||
|  |         bool ShouldDisableSpatialBlend() | ||
|  |         { | ||
|  |             return m_Director == null || | ||
|  |                 targets.Any(selectedTrack => m_Director.GetGenericBinding(selectedTrack) == null); | ||
|  |         } | ||
|  |     } | ||
|  | } |