AudioTrackInspector.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. using System;
  2. using System.Globalization;
  3. using System.Linq;
  4. using System.Text;
  5. using JetBrains.Annotations;
  6. using UnityEditor;
  7. using UnityEditor.Timeline;
  8. using UnityEngine.Playables;
  9. namespace UnityEngine.Timeline
  10. {
  11. [CustomEditor(typeof(AudioTrack))]
  12. [CanEditMultipleObjects]
  13. class AudioTrackInspector : TrackAssetInspector
  14. {
  15. [UsedImplicitly] // Also used by tests
  16. internal static class Styles
  17. {
  18. public const string VolumeControl = "AudioTrackInspector.volume";
  19. public const string StereoPanControl = "AudioTrackInspector.stereoPan";
  20. public const string SpatialBlendControl = "AudioTrackInspector.spatialBlend";
  21. const string k_Indent = " ";
  22. public const string valuesFormatter = "0.###";
  23. public const string mixInfoSectionSeparator = "\n\n";
  24. public static string mixedPropertiesInfo = L10n.Tr("The final {3} is {0}\n" +
  25. "Calculated from:\n" +
  26. k_Indent + "Track: {1}\n" +
  27. k_Indent + "AudioSource: {2}");
  28. }
  29. static StringBuilder s_MixInfoBuilder = new StringBuilder();
  30. SerializedProperty m_VolumeProperty;
  31. SerializedProperty m_StereoPanProperty;
  32. SerializedProperty m_SpatialBlendProperty;
  33. PlayableDirector m_Director;
  34. public override void OnEnable()
  35. {
  36. base.OnEnable();
  37. if (((AudioTrack)target).timelineAsset == TimelineEditor.inspectedAsset)
  38. m_Director = TimelineEditor.inspectedDirector;
  39. m_VolumeProperty = serializedObject.FindProperty("m_TrackProperties.volume");
  40. m_StereoPanProperty = serializedObject.FindProperty("m_TrackProperties.stereoPan");
  41. m_SpatialBlendProperty = serializedObject.FindProperty("m_TrackProperties.spatialBlend");
  42. }
  43. protected override void DrawTrackProperties()
  44. {
  45. // Volume
  46. GUI.SetNextControlName(Styles.VolumeControl);
  47. EditorGUILayout.Slider(m_VolumeProperty, 0.0f, 1.0f, AudioSourceInspector.Styles.volumeLabel);
  48. EditorGUILayout.Space();
  49. // Stereo Pan
  50. GUI.SetNextControlName(Styles.StereoPanControl);
  51. EditorGUIUtility.sliderLabels.SetLabels(AudioSourceInspector.Styles.panLeftLabel, AudioSourceInspector.Styles.panRightLabel);
  52. EditorGUILayout.Slider(m_StereoPanProperty, -1.0f, 1.0f, AudioSourceInspector.Styles.panStereoLabel);
  53. EditorGUIUtility.sliderLabels.SetLabels(null, null);
  54. EditorGUILayout.Space();
  55. // Spatial Blend
  56. using (new EditorGUI.DisabledScope(ShouldDisableSpatialBlend()))
  57. {
  58. GUI.SetNextControlName(Styles.SpatialBlendControl);
  59. EditorGUIUtility.sliderLabels.SetLabels(AudioSourceInspector.Styles.spatialLeftLabel, AudioSourceInspector.Styles.spatialRightLabel);
  60. EditorGUILayout.Slider(m_SpatialBlendProperty, 0.0f, 1.0f, AudioSourceInspector.Styles.spatialBlendLabel);
  61. EditorGUIUtility.sliderLabels.SetLabels(null, null);
  62. }
  63. DrawMixInfoSection();
  64. }
  65. void DrawMixInfoSection()
  66. {
  67. if (m_Director == null || targets.Length > 1)
  68. return;
  69. var binding = m_Director.GetGenericBinding(target) as AudioSource;
  70. if (binding == null)
  71. return;
  72. var audioSourceVolume = binding.volume;
  73. var audioSourcePan = binding.panStereo;
  74. var audioSourceBlend = binding.spatialBlend;
  75. var trackVolume = m_VolumeProperty.floatValue;
  76. var trackPan = m_StereoPanProperty.floatValue;
  77. var trackBlend = m_SpatialBlendProperty.floatValue;
  78. // Skip sections when result is obvious
  79. var skipVolumeInfo = Math.Abs(audioSourceVolume) < float.Epsilon && Math.Abs(trackVolume) < float.Epsilon || // All muted
  80. Math.Abs(audioSourceVolume - 1) < float.Epsilon && Math.Abs(trackVolume - 1) < float.Epsilon; // All max volume
  81. var skipPanInfo = Math.Abs(audioSourcePan) < float.Epsilon && Math.Abs(trackPan) < float.Epsilon || // All centered
  82. Math.Abs(audioSourcePan - 1) < float.Epsilon && Math.Abs(trackPan - 1) < float.Epsilon || // All right
  83. Math.Abs(audioSourcePan - (-1.0f)) < float.Epsilon && Math.Abs(trackPan - (-1.0f)) < float.Epsilon; // All left
  84. var skipBlendInfo = Math.Abs(audioSourceBlend) < float.Epsilon && Math.Abs(trackBlend) < float.Epsilon || // All 2D
  85. Math.Abs(audioSourceBlend - 1) < float.Epsilon && Math.Abs(trackBlend - 1) < float.Epsilon; // All 3D
  86. if (skipVolumeInfo && skipPanInfo && skipBlendInfo)
  87. return;
  88. s_MixInfoBuilder.Length = 0;
  89. if (!skipVolumeInfo)
  90. s_MixInfoBuilder.AppendFormat(
  91. Styles.mixedPropertiesInfo,
  92. (audioSourceVolume * trackVolume).ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture),
  93. trackVolume.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture),
  94. audioSourceVolume.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture),
  95. AudioSourceInspector.Styles.volumeLabel.text);
  96. if (!skipVolumeInfo && !skipPanInfo)
  97. s_MixInfoBuilder.Append(Styles.mixInfoSectionSeparator);
  98. if (!skipPanInfo)
  99. s_MixInfoBuilder.AppendFormat(
  100. Styles.mixedPropertiesInfo,
  101. Mathf.Clamp(audioSourcePan + trackPan, -1.0f, 1.0f).ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture),
  102. trackPan.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture),
  103. audioSourcePan.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture),
  104. AudioSourceInspector.Styles.panStereoLabel.text);
  105. if ((!skipVolumeInfo || !skipPanInfo) && !skipBlendInfo)
  106. s_MixInfoBuilder.Append(Styles.mixInfoSectionSeparator);
  107. if (!skipBlendInfo)
  108. s_MixInfoBuilder.AppendFormat(
  109. Styles.mixedPropertiesInfo,
  110. Mathf.Clamp01(audioSourceBlend + trackBlend).ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture),
  111. trackBlend.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture),
  112. audioSourceBlend.ToString(Styles.valuesFormatter, CultureInfo.InvariantCulture),
  113. AudioSourceInspector.Styles.spatialBlendLabel.text);
  114. EditorGUILayout.Space();
  115. EditorGUILayout.HelpBox(new GUIContent(s_MixInfoBuilder.ToString()));
  116. }
  117. protected override void ApplyChanges()
  118. {
  119. var track = (AudioTrack)target;
  120. if (TimelineEditor.inspectedAsset != track.timelineAsset || TimelineEditor.inspectedDirector == null)
  121. return;
  122. if (TimelineEditor.inspectedDirector.state == PlayState.Playing)
  123. track.LiveLink();
  124. else
  125. TimelineEditor.Refresh(RefreshReason.ContentsModified);
  126. }
  127. bool ShouldDisableSpatialBlend()
  128. {
  129. return m_Director == null ||
  130. targets.Any(selectedTrack => m_Director.GetGenericBinding(selectedTrack) == null);
  131. }
  132. }
  133. }