/// <summary>Draws the sub-inspector for an SFXLayer.</summary> /// <param name="DrawRect">The rect in the list display that this SFXLayer has to be drawn in.</param> /// <param name="Index">The index of this SFXLayer in the Track.</param> /// <param name="IsActive">If the SFXLayer is actively selected.</param> /// <param name="IsFocused">If the SFXLayer is in focus.</param> private void DrawSFXLayerInspector(Rect DrawRect, int Index, bool IsActive, bool IsFocused) { //Shifts rect to create border DrawRect.y += 2; //Calculates commonly used spacings float Spacing = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; float LabelWidth = EditorGUIUtility.labelWidth - 20; float FieldPadding = 20f; //Starts counter for current displayed property int PropertyIndex = 0; //Caches serialised properties SerializedProperty CurrentSFXLayer = SFXLayerListDisplay.serializedProperty.GetArrayElementAtIndex(Index); SerializedProperty NameProperty = CurrentSFXLayer.FindPropertyRelative("LayerName"); SerializedProperty SFXProperty = CurrentSFXLayer.FindPropertyRelative("SFX"); SerializedProperty RandomizeVolumeProperty = CurrentSFXLayer.FindPropertyRelative("RandomizeVolume"); SerializedProperty FixedVolumeProperty = CurrentSFXLayer.FindPropertyRelative("FixedVolume"); SerializedProperty MinVolumeProperty = CurrentSFXLayer.FindPropertyRelative("MinVolume"); SerializedProperty MaxVolumeProperty = CurrentSFXLayer.FindPropertyRelative("MaxVolume"); SerializedProperty RandomizePitchProperty = CurrentSFXLayer.FindPropertyRelative("RandomizePitch"); SerializedProperty FixedPitchProperty = CurrentSFXLayer.FindPropertyRelative("FixedPitch"); SerializedProperty MinPitchProperty = CurrentSFXLayer.FindPropertyRelative("MinPitch"); SerializedProperty MaxPitchProperty = CurrentSFXLayer.FindPropertyRelative("MaxPitch"); SerializedProperty DelayProperty = CurrentSFXLayer.FindPropertyRelative("DelaySFX"); SerializedProperty RandomizeDelayProperty = CurrentSFXLayer.FindPropertyRelative("RandomizeDelay"); SerializedProperty FixedDelayProperty = CurrentSFXLayer.FindPropertyRelative("FixedDelayTime"); SerializedProperty MinDelayProperty = CurrentSFXLayer.FindPropertyRelative("MinDelayTime"); SerializedProperty MaxDelayProperty = CurrentSFXLayer.FindPropertyRelative("MaxDelayTime"); SerializedProperty PriorityProperty = CurrentSFXLayer.FindPropertyRelative("Priority"); SerializedProperty StereoProperty = CurrentSFXLayer.FindPropertyRelative("StereoPan"); SerializedProperty SpatialProperty = CurrentSFXLayer.FindPropertyRelative("SpatialBlend"); SerializedProperty ReverbProperty = CurrentSFXLayer.FindPropertyRelative("ReverbZoneMix"); SerializedProperty BypassEffectsProperty = CurrentSFXLayer.FindPropertyRelative("BypassEffects"); SerializedProperty BypassReverbProperty = CurrentSFXLayer.FindPropertyRelative("BypassReverbZones"); SerializedProperty MuteProperty = CurrentSFXLayer.FindPropertyRelative("Mute"); //Draws a property with a custom style Action <SerializedProperty, string, string, GUIStyle> DrawPropertyStyled = (SerializedProperty Property, string PropertyName, string Tooltip, GUIStyle TextStyle) => { //Draws label EditorGUI.LabelField(new Rect(DrawRect.x, (PropertyIndex + 1) * Spacing + DrawRect.y, LabelWidth, EditorGUIUtility.singleLineHeight), new GUIContent(PropertyName, Tooltip), TextStyle); //Draws property field EditorGUI.PropertyField(new Rect(DrawRect.x + LabelWidth, (PropertyIndex + 1) * Spacing + DrawRect.y, DrawRect.width - LabelWidth - FieldPadding, EditorGUIUtility.singleLineHeight), Property, GUIContent.none); //Increments property counter PropertyIndex++; }; //Draws a slider for a property Action <SerializedProperty, string, string, float, float> DrawSlider = (SerializedProperty Property, string PropertyName, string Tooltip, float MinLim, float MaxLim) => { //Draws label EditorGUI.LabelField(new Rect(DrawRect.x, (PropertyIndex + 1) * Spacing + DrawRect.y, LabelWidth, EditorGUIUtility.singleLineHeight), new GUIContent(PropertyName, Tooltip)); //Draws the slider Property.floatValue = EditorGUI.Slider(new Rect(DrawRect.x + LabelWidth, (PropertyIndex + 1) * Spacing + DrawRect.y, DrawRect.width - LabelWidth - FieldPadding, EditorGUIUtility.singleLineHeight), Property.floatValue, MinLim, MaxLim); //Increments property counter PropertyIndex++; }; //Draws an int slider for a property Action <SerializedProperty, string, string, int, int> DrawIntSlider = (SerializedProperty Property, string PropertyName, string Tooltip, int MinLim, int MaxLim) => { //Draws label EditorGUI.LabelField(new Rect(DrawRect.x, (PropertyIndex + 1) * Spacing + DrawRect.y, LabelWidth, EditorGUIUtility.singleLineHeight), new GUIContent(PropertyName, Tooltip)); //Draws the slider Property.intValue = (int)EditorGUI.Slider(new Rect(DrawRect.x + LabelWidth, (PropertyIndex + 1) * Spacing + DrawRect.y, DrawRect.width - LabelWidth - FieldPadding, EditorGUIUtility.singleLineHeight), Property.intValue, MinLim, MaxLim); //Increments property counter PropertyIndex++; }; //Draws a min max slider for a property Action <SerializedProperty, SerializedProperty, string, string, float, float> DrawMinMaxSlider = (SerializedProperty PropertyLeft, SerializedProperty PropertyRight, string PropertyName, string Tooltip, float MinLim, float MaxLim) => { //Draws label EditorGUI.LabelField(new Rect(DrawRect.x, (PropertyIndex + 1) * Spacing + DrawRect.y, LabelWidth, EditorGUIUtility.singleLineHeight), new GUIContent(PropertyName, Tooltip)); //Draws the slider AMPEditorFields.MinMaxSlider(new Rect(DrawRect.x + LabelWidth, (PropertyIndex + 1) * Spacing + DrawRect.y, DrawRect.width - LabelWidth - FieldPadding, EditorGUIUtility.singleLineHeight), GUIContent.none, PropertyLeft, PropertyRight, MinLim, MaxLim); //Increments property counter PropertyIndex++; }; //Draws a property Action <SerializedProperty, string, string> DrawProperty = (SerializedProperty Property, string PropertyName, string Tooltip) => { DrawPropertyStyled(Property, PropertyName, Tooltip, EditorStyles.label); }; //Gets and draws SFXLayer name string Name = NameProperty.stringValue; if (string.IsNullOrEmpty(Name.Trim())) { Name = "Untitled"; } EditorGUI.LabelField(new Rect(DrawRect.x, DrawRect.y, DrawRect.width - 90, EditorGUIUtility.singleLineHeight), Name, (SFXObjectInstance.SFXLayers[Index].SFX == null && SFXObjectInstance.CollapseEditions ? InvalidBoldStyle : EditorStyles.boldLabel)); //Draws SFX length if (SFXObjectInstance.SFXLayers[Index].SFX != null) { EditorGUI.LabelField(new Rect((DrawRect.x + DrawRect.width) / 2 - 40, DrawRect.y, 80, EditorGUIUtility.singleLineHeight), StringFormatting.FormatTime(SFXObjectInstance.SFXLayers[Index].SFX.length), CenteredMiniLabel); } //Displays basic properties if uncollapsed if (!SFXObjectInstance.CollapseEditions) { DrawProperty(NameProperty, "Layer Name", "(Optional) The name of the Edition."); DrawPropertyStyled(SFXProperty, "SFX", "The audio to be played in this SFXLayer.", (SFXObjectInstance.SFXLayers[Index].SFX == null ? InvalidStyle : EditorStyles.label)); //Shows full properties if the SFX is not null if (SFXObjectInstance.SFXLayers[Index].SFX != null) { //Volume properties DrawProperty(RandomizeVolumeProperty, "Randomize Volume", "If the volume of the sound should be randomised."); if (SFXObjectInstance.SFXLayers[Index].RandomizeVolume) { DrawMinMaxSlider(MinVolumeProperty, MaxVolumeProperty, "Volume", "The range of values that the volume of the SFXLayer can be.", 0, 1); EditorGUI.LabelField(new Rect(DrawRect.x + 82, PropertyIndex * Spacing + DrawRect.y, LabelWidth - 82, EditorGUIUtility.singleLineHeight), NumberManipulation.DecimalPlaces(SFXObjectInstance.SFXLayers[Index].MinVolume, 2).ToString() + " - " + NumberManipulation.DecimalPlaces(SFXObjectInstance.SFXLayers[Index].MaxVolume, 2).ToString(), CenteredMiniLabel); } else { DrawSlider(FixedVolumeProperty, "Volume", "The volume of the SFXLayer.", 0, 1); } //Pitch properties DrawProperty(RandomizePitchProperty, "Randomize Pitch", "If the pitch of the sound should be randomised."); if (SFXObjectInstance.SFXLayers[Index].RandomizePitch) { DrawMinMaxSlider(MinPitchProperty, MaxPitchProperty, "Pitch", "The range of values that the pitch of the SFXLayer can be.", 0, 3); EditorGUI.LabelField(new Rect(DrawRect.x + 82, PropertyIndex * Spacing + DrawRect.y, LabelWidth - 82, EditorGUIUtility.singleLineHeight), NumberManipulation.DecimalPlaces(SFXObjectInstance.SFXLayers[Index].MinPitch, 2).ToString() + " - " + NumberManipulation.DecimalPlaces(SFXObjectInstance.SFXLayers[Index].MaxPitch, 2).ToString(), CenteredMiniLabel); } else { DrawSlider(FixedPitchProperty, "Pitch", "The pitch of the SFXLayer.", 0, 3); } //Delay properties DrawProperty(DelayProperty, "Delay", "If there should be a delay before playing this SFXLayer."); if (SFXObjectInstance.SFXLayers[Index].DelaySFX) { DrawProperty(RandomizeDelayProperty, "Randomize Delay", "If the delay time should be randomized."); if (SFXObjectInstance.SFXLayers[Index].RandomizeDelay) { DrawProperty(MinDelayProperty, "Minimum Delay", "Minimum duration of the delay."); DrawProperty(MaxDelayProperty, "Maximum Delay", "Maximum duration of the delay."); MinDelayProperty.floatValue = Mathf.Max(0, MinDelayProperty.floatValue); MaxDelayProperty.floatValue = Mathf.Max(SFXObjectInstance.SFXLayers[Index].MinDelayTime, MaxDelayProperty.floatValue); } else { DrawProperty(FixedDelayProperty, "Delay Duration", "Duration of the delay."); FixedDelayProperty.floatValue = Mathf.Max(0, FixedDelayProperty.floatValue); } } //Other properties DrawProperty(MuteProperty, "Mute", "Mutes the sound."); DrawProperty(BypassEffectsProperty, "Bypass Effects", "Bypass any applied effects on the SFXLayer."); DrawProperty(BypassReverbProperty, "Bypass Reverb Zones", "Bypasses any reverb zones"); DrawIntSlider(PriorityProperty, "Priority", "The priority of the SFXLayer.", 0, 256); EditorGUI.LabelField(new Rect(DrawRect.x + LabelWidth, PropertyIndex * Spacing + DrawRect.y + 8, 30, EditorGUIUtility.singleLineHeight), "High", LeftMiniLabel); EditorGUI.LabelField(new Rect(DrawRect.x + DrawRect.width - FieldPadding - 95, PropertyIndex * Spacing + DrawRect.y + 8, 40, EditorGUIUtility.singleLineHeight), "Low", RightMiniLabel); DrawSlider(StereoProperty, "Stero Pan", "Pans a playing sound in a stereo way (left or right). This only applies to sounds that are Mono or Stereo.", -1, 1); EditorGUI.LabelField(new Rect(DrawRect.x + LabelWidth, PropertyIndex * Spacing + DrawRect.y + 8, 25, EditorGUIUtility.singleLineHeight), "Left", LeftMiniLabel); EditorGUI.LabelField(new Rect(DrawRect.x + DrawRect.width - FieldPadding - 95, PropertyIndex * Spacing + DrawRect.y + 8, 40, EditorGUIUtility.singleLineHeight), "Right", RightMiniLabel); DrawSlider(SpatialProperty, "Spatial Blend", "Sets how much this SFXLayer is affected by 3D spatialisation calculations. 0.0 makes the sound full 2D, 1.0 makes it full 3D.", 0, 1); EditorGUI.LabelField(new Rect(DrawRect.x + LabelWidth, PropertyIndex * Spacing + DrawRect.y + 8, 25, EditorGUIUtility.singleLineHeight), "2D", LeftMiniLabel); EditorGUI.LabelField(new Rect(DrawRect.x + DrawRect.width - FieldPadding - 95, PropertyIndex * Spacing + DrawRect.y + 8, 40, EditorGUIUtility.singleLineHeight), "3D", RightMiniLabel); DrawSlider(ReverbProperty, "Reverb Zone Mix", "The amount by which the signal from the AudioSource will be mixed into the global reverb associated with the Reverb Zones.", 0, 1.1f); } else { //Displays error if no SFX is selected EditorGUI.HelpBox(new Rect(DrawRect.x, (PropertyIndex + 1) * Spacing + DrawRect.y + 2f, DrawRect.width - FieldPadding, 30), "SFX required. Please assign an AudioClip to this SFXLayer.", MessageType.Error); } } }
//Draws Track inspector public override void OnInspectorGUI() { //Updates the SFXObject object serializedObject.Update(); CreateStyles(); //Banner display Rect BannerRect = GUILayoutUtility.GetRect(0.0f, 0.0f); BannerRect.height = Screen.width * 250 / 1600; GUILayout.Space(BannerRect.height); GUI.Label(BannerRect, Banner); //Displays SFXObject name GUILayout.BeginVertical(BackgroundStyles[0], GUILayout.Height(EditorGUIUtility.singleLineHeight)); EditorGUILayout.PropertyField(SFXName, new GUIContent("SFX Name", "(Optional) The name of this SFXObject.")); GUILayout.EndVertical(); //Displays volume settings GUILayout.BeginVertical(BackgroundStyles[1], GUILayout.Height(2 * EditorGUIUtility.singleLineHeight)); EditorGUILayout.PropertyField(RandomizeVolume, new GUIContent("Randomize Volume", "If the volume of the sound should be randomized.")); Rect VolumeRect = EditorGUILayout.GetControlRect(); if (SFXObjectInstance.RandomizeVolume) { AMPEditorFields.MinMaxSlider(VolumeRect, new GUIContent("Volume", "The range of values that the volume multiplier of the SFXObject can be."), MinVolume, MaxVolume, 0, 1); EditorGUI.LabelField(new Rect(VolumeRect.x + 82, VolumeRect.y, EditorGUIUtility.labelWidth - 20 - 82, EditorGUIUtility.singleLineHeight), NumberManipulation.DecimalPlaces(SFXObjectInstance.MinVolume, 2).ToString() + " - " + NumberManipulation.DecimalPlaces(SFXObjectInstance.MaxVolume, 2).ToString(), CenteredMiniLabel); } else { EditorGUI.Slider(VolumeRect, FixedVolume, 0, 1, new GUIContent("Volume", "The volume multiplier of the SFXObject.")); } GUILayout.EndVertical(); //Displays pitch settings GUILayout.BeginVertical(BackgroundStyles[0], GUILayout.Height(2 * EditorGUIUtility.singleLineHeight)); EditorGUILayout.PropertyField(RandomizePitch, new GUIContent("Randomize Pitch", "If the pitch of the sound should be randomized.")); Rect PitchRect = EditorGUILayout.GetControlRect(); if (SFXObjectInstance.RandomizePitch) { AMPEditorFields.MinMaxSlider(PitchRect, new GUIContent("Pitch", "The range of values that the pitch multiplier of the SFXObject can be."), MinPitch, MaxPitch, 0, 3); EditorGUI.LabelField(new Rect(PitchRect.x + 82, PitchRect.y, EditorGUIUtility.labelWidth - 20 - 82, EditorGUIUtility.singleLineHeight), NumberManipulation.DecimalPlaces(SFXObjectInstance.MinPitch, 2).ToString() + " - " + NumberManipulation.DecimalPlaces(SFXObjectInstance.MaxPitch, 2).ToString(), CenteredMiniLabel); } else { EditorGUI.Slider(PitchRect, FixedPitch, 0, 3, new GUIContent("Pitch", "The Pitch multiplier of the SFXObject.")); } GUILayout.EndVertical(); //Displays delay settings GUILayout.BeginVertical(BackgroundStyles[1], GUILayout.Height((SFXObjectInstance.DelaySFX ? (SFXObjectInstance.RandomizeDelay ? 4 : 3) : 1) * EditorGUIUtility.singleLineHeight)); EditorGUILayout.PropertyField(DelaySFX, new GUIContent("Delay", "If there should be a global delay before playing this SFXObject.")); if (SFXObjectInstance.DelaySFX) { EditorGUILayout.PropertyField(RandomizeDelay, new GUIContent("Randomize Delay", "If the delay time should be randomized.")); if (SFXObjectInstance.RandomizeDelay) { MinDelay.floatValue = Mathf.Max(0f, EditorGUILayout.FloatField(new GUIContent("Minimum Delay", "Minimum duration of the delay."), SFXObjectInstance.MinDelayTime)); MaxDelay.floatValue = Mathf.Max(SFXObjectInstance.MinDelayTime, EditorGUILayout.FloatField(new GUIContent("Maximum Delay", "Maximum duration of the delay."), SFXObjectInstance.MaxDelayTime)); } else { FixedDelay.floatValue = Mathf.Max(0f, EditorGUILayout.FloatField(new GUIContent("Delay Duration", "Duration of the delay."), SFXObjectInstance.FixedDelayTime)); } } GUILayout.EndVertical(); //Displays polyphony settings GUILayout.BeginVertical(BackgroundStyles[0], GUILayout.Height((SFXObjectInstance.LimitPolyphony ? 2 : 1) * EditorGUIUtility.singleLineHeight)); EditorGUILayout.PropertyField(LimitPolyphony, new GUIContent("Polyphony Limit", "If polyphony limits should be applied. With polyphony limiting, the behaviour of simultaneous and overlapping sounds is controlled.")); if (SFXObjectInstance.LimitPolyphony) { //EditorGUILayout.PropertyField(MaxVoices, new GUIContent("Maximum Voices", "The maximum number of voices for this SFXObject, or how many can be played in tandem. 0 results in infinite voices.")); EditorGUILayout.PropertyField(MinSeparation, new GUIContent("Minimum Separation", "The minimum time separation between subsequent plays of this SFXObject; if the duration has not been surpassed, the SFXObject will not be played.")); MaxVoices.intValue = Mathf.Max(0, MaxVoices.intValue); MinSeparation.floatValue = Mathf.Max(0, MinSeparation.floatValue); } GUILayout.EndVertical(); //Preview GUILayout.BeginVertical(BackgroundStyles[1], GUILayout.Height(EditorGUIUtility.singleLineHeight)); EditorGUILayout.BeginHorizontal(); GUI.enabled = SFXManager.Main; EditorGUILayout.LabelField(new GUIContent("Preview", "Preview options for the SFXObject. Only available at runtime.")); if (GUILayout.Button(new GUIContent("Play", "Plays the SFXObject."))) { SFXManager.Main.Play(SFXObjectInstance); } GUI.enabled = true; EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); //Adds new SFXLayer if the list is empty if (SFXObjectInstance.SFXLayers.Length == 0) { SFXObjectInstance.SFXLayers = new SFXLayer[1]; SFXObjectInstance.SFXLayers[0].FixedVolume = 1f; SFXObjectInstance.SFXLayers[0].FixedPitch = 1f; } //Enables SFXLayer removal button if more than one is present SFXLayerListDisplay.displayRemove = SFXObjectInstance.SFXLayers.Length > 1; //Draws list and updates SFXObject SFXLayerListDisplay.DoLayoutList(); serializedObject.ApplyModifiedProperties(); }