public override void OnInspectorGUI()
    {
        EditorGUIUtility.LookLikeControls();

        EditorGUI.indentLevel = 0;
        var isDirty = false;

        _group = (DynamicSoundGroup)target;

        _group = RescanChildren(_group);

        var dsgc = _group.transform.parent;
        DynamicSoundGroupCreator creator = null;

        if (dsgc != null)
        {
            creator = dsgc.GetComponent <DynamicSoundGroupCreator>();
        }

        if (creator == null)
        {
            isValid = false;
        }

        if (!isValid)
        {
            return;
        }

        var isInProjectView = DTGUIHelper.IsPrefabInProjectView(_group);

        if (MasterAudioInspectorResources.logoTexture != null)
        {
            DTGUIHelper.ShowHeaderTexture(MasterAudioInspectorResources.logoTexture);
        }

        EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
        GUI.contentColor = Color.green;
        if (GUILayout.Button(new GUIContent("Back to Dynamic Sound Group Creator", "Select Group in Hierarchy"), EditorStyles.toolbarButton, GUILayout.Width(220)))
        {
            Selection.activeObject = _group.transform.parent.gameObject;
        }
        GUI.contentColor = Color.white;
        GUILayout.FlexibleSpace();
        EditorGUILayout.EndHorizontal();

        var newVol = EditorGUILayout.Slider("Group Master Volume", _group.groupMasterVolume, 0f, 1f);

        if (newVol != _group.groupMasterVolume)
        {
            UndoHelper.RecordObjectPropertyForUndo(_group, "change Group Master Volume");
            _group.groupMasterVolume = newVol;
        }

        var newVarSequence = (MasterAudioGroup.VariationSequence)EditorGUILayout.EnumPopup("Variation Sequence", _group.curVariationSequence);

        if (newVarSequence != _group.curVariationSequence)
        {
            UndoHelper.RecordObjectPropertyForUndo(_group, "change Variation Sequence");
            _group.curVariationSequence = newVarSequence;
        }

        if (_group.curVariationSequence == MasterAudioGroup.VariationSequence.TopToBottom)
        {
            var newUseInactive = EditorGUILayout.BeginToggleGroup("Refill Variation Pool After Inactive Time", _group.useInactivePeriodPoolRefill);
            if (newUseInactive != _group.useInactivePeriodPoolRefill)
            {
                UndoHelper.RecordObjectPropertyForUndo(_group, "toggle Inactive Refill");
                _group.useInactivePeriodPoolRefill = newUseInactive;
            }

            EditorGUI.indentLevel = 1;
            var newInactivePeriod = EditorGUILayout.Slider("Inactive Time (sec)", _group.inactivePeriodSeconds, .2f, 30f);
            if (newInactivePeriod != _group.inactivePeriodSeconds)
            {
                UndoHelper.RecordObjectPropertyForUndo(_group, "change Inactive Time");
                _group.inactivePeriodSeconds = newInactivePeriod;
            }

            EditorGUILayout.EndToggleGroup();
        }

        EditorGUI.indentLevel = 0;
        var newVarMode = (MasterAudioGroup.VariationMode)EditorGUILayout.EnumPopup("Variation Mode", _group.curVariationMode);

        if (newVarMode != _group.curVariationMode)
        {
            UndoHelper.RecordObjectPropertyForUndo(_group, "change Variation Mode");
            _group.curVariationMode = newVarMode;
        }

        EditorGUI.indentLevel = 1;
        switch (_group.curVariationMode)
        {
        case MasterAudioGroup.VariationMode.LoopedChain:
            DTGUIHelper.ShowColorWarning("*In this mode, only one Variation can be played at a time.");

            var newLoopMode = (MasterAudioGroup.ChainedLoopLoopMode)EditorGUILayout.EnumPopup("Loop Mode", _group.chainLoopMode);
            if (newLoopMode != _group.chainLoopMode)
            {
                UndoHelper.RecordObjectPropertyForUndo(_group, "change Loop Mode");
                _group.chainLoopMode = newLoopMode;
            }

            if (_group.chainLoopMode == MasterAudioGroup.ChainedLoopLoopMode.NumberOfLoops)
            {
                var newLoopCount = EditorGUILayout.IntSlider("Number of Loops", _group.chainLoopNumLoops, 1, 500);
                if (newLoopCount != _group.chainLoopNumLoops)
                {
                    UndoHelper.RecordObjectPropertyForUndo(_group, "change Number of Loops");
                    _group.chainLoopNumLoops = newLoopCount;
                }
            }

            var newDelayMin = EditorGUILayout.Slider("Clip Change Delay Min", _group.chainLoopDelayMin, 0f, 20f);
            if (newDelayMin != _group.chainLoopDelayMin)
            {
                if (_group.chainLoopDelayMax < newDelayMin)
                {
                    _group.chainLoopDelayMax = newDelayMin;
                }
                UndoHelper.RecordObjectPropertyForUndo(_group, "change Chained Clip Delay Min");
                _group.chainLoopDelayMin = newDelayMin;
            }

            var newDelayMax = EditorGUILayout.Slider("Clip Change Delay Max", _group.chainLoopDelayMax, 0f, 20f);
            if (newDelayMax != _group.chainLoopDelayMax)
            {
                if (newDelayMax < _group.chainLoopDelayMin)
                {
                    newDelayMax = _group.chainLoopDelayMin;
                }
                UndoHelper.RecordObjectPropertyForUndo(_group, "change Chained Clip Delay Max");
                _group.chainLoopDelayMax = newDelayMax;
            }
            break;

        case MasterAudioGroup.VariationMode.Normal:
            var newRetrigger = EditorGUILayout.IntSlider("Retrigger Percentage", _group.retriggerPercentage, 0, 100);
            if (newRetrigger != _group.retriggerPercentage)
            {
                UndoHelper.RecordObjectPropertyForUndo(_group, "change Retrigger Percentage");
                _group.retriggerPercentage = newRetrigger;
            }

            var newLimitPoly = EditorGUILayout.Toggle("Limit Polyphony", _group.limitPolyphony);
            if (newLimitPoly != _group.limitPolyphony)
            {
                UndoHelper.RecordObjectPropertyForUndo(_group, "toggle Limit Polyphony");
                _group.limitPolyphony = newLimitPoly;
            }
            if (_group.limitPolyphony)
            {
                int maxVoices = 0;
                for (var i = 0; i < _group.groupVariations.Count; i++)
                {
                    var variation = _group.groupVariations[i];
                    maxVoices += variation.weight;
                }

                var newVoiceLimit = EditorGUILayout.IntSlider("Polyphony Voice Limit", _group.voiceLimitCount, 1, maxVoices);
                if (newVoiceLimit != _group.voiceLimitCount)
                {
                    UndoHelper.RecordObjectPropertyForUndo(_group, "change Polyphony Voice Limit");
                    _group.voiceLimitCount = newVoiceLimit;
                }
            }

            var newLimitMode = (MasterAudioGroup.LimitMode)EditorGUILayout.EnumPopup("Replay Limit Mode", _group.limitMode);
            if (newLimitMode != _group.limitMode)
            {
                UndoHelper.RecordObjectPropertyForUndo(_group, "change Replay Limit Mode");
                _group.limitMode = newLimitMode;
            }

            switch (_group.limitMode)
            {
            case MasterAudioGroup.LimitMode.FrameBased:
                var newFrameLimit = EditorGUILayout.IntSlider("Min Frames Between", _group.limitPerXFrames, 1, 120);
                if (newFrameLimit != _group.limitPerXFrames)
                {
                    UndoHelper.RecordObjectPropertyForUndo(_group, "change Min Frames Between");
                    _group.limitPerXFrames = newFrameLimit;
                }
                break;

            case MasterAudioGroup.LimitMode.TimeBased:
                var newMinTime = EditorGUILayout.Slider("Min Seconds Between", _group.minimumTimeBetween, 0.1f, 10f);
                if (newMinTime != _group.minimumTimeBetween)
                {
                    UndoHelper.RecordObjectPropertyForUndo(_group, "change Min Seconds Between");
                    _group.minimumTimeBetween = newMinTime;
                }
                break;
            }
            break;

        case MasterAudioGroup.VariationMode.Dialog:
            DTGUIHelper.ShowColorWarning("*In this mode, only one Variation can be played at a time.");

            var newUseDialog = EditorGUILayout.Toggle("Dialog Custom Fade?", _group.useDialogFadeOut);
            if (newUseDialog != _group.useDialogFadeOut)
            {
                UndoHelper.RecordObjectPropertyForUndo(_group, "toggle Dialog Custom Fade?");
                _group.useDialogFadeOut = newUseDialog;
            }

            if (_group.useDialogFadeOut)
            {
                var newFadeTime = EditorGUILayout.Slider("Custom Fade Out Time", _group.dialogFadeOutTime, 0.1f, 20f);
                if (newFadeTime != _group.dialogFadeOutTime)
                {
                    UndoHelper.RecordObjectPropertyForUndo(_group, "change Custom Fade Out Time");
                    _group.dialogFadeOutTime = newFadeTime;
                }
            }
            break;
        }

        EditorGUI.indentLevel = 0;

        var newBulkMode = (MasterAudio.AudioLocation)EditorGUILayout.EnumPopup("Variation Create Mode", _group.bulkVariationMode);

        if (newBulkMode != _group.bulkVariationMode)
        {
            UndoHelper.RecordObjectPropertyForUndo(_group, "change Bulk Variation Mode");
            _group.bulkVariationMode = newBulkMode;
        }
        if (_group.bulkVariationMode == MasterAudio.AudioLocation.ResourceFile)
        {
            DTGUIHelper.ShowColorWarning("*Resource mode: make sure to drag from Resource folders only.");
        }

        var newLog = EditorGUILayout.Toggle("Log Sounds", _group.logSound);

        if (newLog != _group.logSound)
        {
            UndoHelper.RecordObjectPropertyForUndo(_group, "toggle Log Sounds");
            _group.logSound = newLog;
        }

        int?deadChildIndex = null;

        if (!Application.isPlaying)
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(4);
            GUILayout.Label("Actions", EditorStyles.wordWrappedLabel, GUILayout.Width(50f));
            GUILayout.Space(96);
            GUI.contentColor = Color.green;
            if (GUILayout.Button(new GUIContent("Equalize Weights", "Reset Weights to one"), EditorStyles.toolbarButton, GUILayout.Width(120)))
            {
                isDirty = true;
                EqualizeWeights(_group);
            }

            GUILayout.Space(10);
            if (GUILayout.Button(new GUIContent("Equalize Variation Volumes"), EditorStyles.toolbarButton, GUILayout.Width(150)))
            {
                EqualizeVariationVolumes(_group.groupVariations);
            }

            GUI.contentColor = Color.white;
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Separator();
        }

        if (!Application.isPlaying)
        {
            // new variation settings
            EditorGUILayout.BeginVertical();
            var anEvent = Event.current;

            if (isInProjectView)
            {
                DTGUIHelper.ShowLargeBarAlert("*You are in Project View and cannot create Variations.");
                DTGUIHelper.ShowLargeBarAlert("*Pull this prefab into the Scene to create Variations.");
            }
            else
            {
                GUI.color = Color.yellow;

                var dragArea = GUILayoutUtility.GetRect(0f, 35f, GUILayout.ExpandWidth(true));
                GUI.Box(dragArea, "Drag Audio clips here to create Variations!");

                GUI.color = Color.white;

                switch (anEvent.type)
                {
                case EventType.DragUpdated:
                case EventType.DragPerform:
                    if (!dragArea.Contains(anEvent.mousePosition))
                    {
                        break;
                    }

                    DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                    if (anEvent.type == EventType.DragPerform)
                    {
                        DragAndDrop.AcceptDrag();

                        foreach (var dragged in DragAndDrop.objectReferences)
                        {
                            var aClip = dragged as AudioClip;
                            if (aClip == null)
                            {
                                continue;
                            }

                            CreateVariation(_group, aClip);
                        }
                    }
                    Event.current.Use();
                    break;
                }
            }
            EditorGUILayout.EndVertical();
            // end new variation settings
        }

        if (_group.groupVariations.Count == 0)
        {
            DTGUIHelper.ShowRedError("You currently have no Variations.");
        }
        else
        {
            _group.groupVariations.Sort(delegate(DynamicGroupVariation x, DynamicGroupVariation y) {
                return(x.name.CompareTo(y.name));
            });

            for (var i = 0; i < _group.groupVariations.Count; i++)
            {
                var variation = _group.groupVariations[i];
                EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
                EditorGUILayout.LabelField(variation.name, EditorStyles.boldLabel);

                GUILayout.FlexibleSpace();

                if (GUILayout.Button(new GUIContent(MasterAudioInspectorResources.gearTexture, "Click to goto Variation"), EditorStyles.toolbarButton, GUILayout.Width(40)))
                {
                    Selection.activeObject = variation;
                }

                if (!Application.isPlaying)
                {
                    if (GUILayout.Button(new GUIContent(MasterAudioInspectorResources.deleteTexture, "Click to delete this Variation"), EditorStyles.toolbarButton, GUILayout.Width(40)))
                    {
                        deadChildIndex = i;
                        isDirty        = true;
                    }
                }

                var buttonPressed = DTGUIHelper.AddDynamicGroupButtons(_group);
                switch (buttonPressed)
                {
                case DTGUIHelper.DTFunctionButtons.Play:
                    if (variation.audLocation == MasterAudio.AudioLocation.ResourceFile)
                    {
                        creator.PreviewerInstance.Stop();
                        creator.PreviewerInstance.PlayOneShot(Resources.Load(variation.resourceFileName) as AudioClip);
                    }
                    else
                    {
                        variation.audio.Stop();
                        variation.audio.Play();
                    }
                    isDirty = true;
                    break;

                case DTGUIHelper.DTFunctionButtons.Stop:
                    if (variation.audLocation == MasterAudio.AudioLocation.ResourceFile)
                    {
                        creator.PreviewerInstance.Stop();
                    }
                    else
                    {
                        variation.audio.Stop();
                    }
                    isDirty = true;
                    break;
                }

                EditorGUILayout.EndHorizontal();

                if (!Application.isPlaying)
                {
                    DTGUIHelper.ShowColorWarning("*Fading & random settings are ignored by preview in edit mode.");
                }
                if (variation.audio == null)
                {
                    DTGUIHelper.ShowRedError(string.Format("The Variation: '{0}' has no Audio Source.", variation.name));
                    break;
                }

                var oldLocation = variation.audLocation;
                var newLocation = (MasterAudio.AudioLocation)EditorGUILayout.EnumPopup("Audio Origin", variation.audLocation);
                if (newLocation != variation.audLocation)
                {
                    UndoHelper.RecordObjectPropertyForUndo(variation, "change Audio Origin");
                    variation.audLocation = newLocation;
                }

                switch (variation.audLocation)
                {
                case MasterAudio.AudioLocation.Clip:
                    var newClip = (AudioClip)EditorGUILayout.ObjectField("Audio Clip", variation.audio.clip, typeof(AudioClip), false);
                    if (newClip != variation.audio.clip)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation.audio, "change Audio Clip");
                        variation.audio.clip = newClip;
                    }
                    break;

                case MasterAudio.AudioLocation.ResourceFile:
                    if (oldLocation != variation.audLocation)
                    {
                        if (variation.audio.clip != null)
                        {
                            Debug.Log("Audio clip removed to prevent unnecessary memory usage on Resource file Variation.");
                        }
                        variation.audio.clip = null;
                    }

                    EditorGUILayout.BeginVertical();
                    var anEvent = Event.current;

                    GUI.color = Color.yellow;
                    var dragArea = GUILayoutUtility.GetRect(0f, 20f, GUILayout.ExpandWidth(true));
                    GUI.Box(dragArea, "Drag Resource Audio clip here to use its name!");
                    GUI.color = Color.white;

                    switch (anEvent.type)
                    {
                    case EventType.DragUpdated:
                    case EventType.DragPerform:
                        if (!dragArea.Contains(anEvent.mousePosition))
                        {
                            break;
                        }

                        DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                        if (anEvent.type == EventType.DragPerform)
                        {
                            DragAndDrop.AcceptDrag();

                            foreach (var dragged in DragAndDrop.objectReferences)
                            {
                                var aClip = dragged as AudioClip;
                                if (aClip == null)
                                {
                                    continue;
                                }

                                UndoHelper.RecordObjectPropertyForUndo(variation, "change Resource Filename");
                                variation.resourceFileName = aClip.name;
                            }
                        }
                        Event.current.Use();
                        break;
                    }
                    EditorGUILayout.EndVertical();

                    var newFilename = EditorGUILayout.TextField("Resource Filename", variation.resourceFileName);
                    if (newFilename != variation.resourceFileName)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change Resource Filename");
                        variation.resourceFileName = newFilename;
                    }
                    break;
                }

                var newVolume = EditorGUILayout.Slider("Volume", variation.audio.volume, 0f, 1f);
                if (newVolume != variation.audio.volume)
                {
                    UndoHelper.RecordObjectPropertyForUndo(variation.audio, "change Volume");
                    variation.audio.volume = newVolume;
                }

                var newPitch = EditorGUILayout.Slider("Pitch", variation.audio.pitch, -3f, 3f);
                if (newPitch != variation.audio.pitch)
                {
                    UndoHelper.RecordObjectPropertyForUndo(variation.audio, "change Pitch");
                    variation.audio.pitch = newPitch;
                }

                var newLoop = EditorGUILayout.Toggle("Loop Clip", variation.audio.loop);
                if (newLoop != variation.audio.loop)
                {
                    UndoHelper.RecordObjectPropertyForUndo(variation.audio, "toggle Loop Clip");
                    variation.audio.loop = newLoop;
                }

                EditorUtility.SetDirty(variation.audio);

                var newWeight = EditorGUILayout.IntSlider("Weight (Instances)", variation.weight, 0, 100);
                if (newWeight != variation.weight)
                {
                    UndoHelper.RecordObjectPropertyForUndo(variation, "change Weight");
                    variation.weight = newWeight;
                }

                if (variation.HasActiveFXFilter)
                {
                    var newFxTailTime = EditorGUILayout.Slider("FX Tail Time", variation.fxTailTime, 0f, 10f);
                    if (newFxTailTime != variation.fxTailTime)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change FX Tail Time");
                        variation.fxTailTime = newFxTailTime;
                    }
                }

                var newUseRndPitch = EditorGUILayout.BeginToggleGroup("Use Random Pitch", variation.useRandomPitch);
                if (newUseRndPitch != variation.useRandomPitch)
                {
                    UndoHelper.RecordObjectPropertyForUndo(variation, "toggle Use Random Pitch");
                    variation.useRandomPitch = newUseRndPitch;
                }

                if (variation.useRandomPitch)
                {
                    var newMode = (SoundGroupVariation.RandomPitchMode)EditorGUILayout.EnumPopup("Pitch Compute Mode", variation.randomPitchMode);
                    if (newMode != variation.randomPitchMode)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change Pitch Compute Mode");
                        variation.randomPitchMode = newMode;
                    }

                    var newPitchMin = EditorGUILayout.Slider("Random Pitch Min", variation.randomPitchMin, -3f, 3f);
                    if (newPitchMin != variation.randomPitchMin)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change Random Pitch Min");
                        variation.randomPitchMin = newPitchMin;
                        if (variation.randomPitchMax <= variation.randomPitchMin)
                        {
                            variation.randomPitchMax = variation.randomPitchMin;
                        }
                    }

                    var newPitchMax = EditorGUILayout.Slider("Random Pitch Max", variation.randomPitchMax, -3f, 3f);
                    if (newPitchMax != variation.randomPitchMax)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change Random Pitch Max");
                        variation.randomPitchMax = newPitchMax;
                        if (variation.randomPitchMin > variation.randomPitchMax)
                        {
                            variation.randomPitchMin = variation.randomPitchMax;
                        }
                    }
                }

                EditorGUILayout.EndToggleGroup();

                var newUseRndVol = EditorGUILayout.BeginToggleGroup("Use Random Volume", variation.useRandomVolume);
                if (newUseRndVol != variation.useRandomVolume)
                {
                    UndoHelper.RecordObjectPropertyForUndo(variation, "toggle Use Random Volume");
                    variation.useRandomVolume = newUseRndVol;
                }

                if (variation.useRandomVolume)
                {
                    var newMode = (SoundGroupVariation.RandomVolumeMode)EditorGUILayout.EnumPopup("Volume Compute Mode", variation.randomVolumeMode);
                    if (newMode != variation.randomVolumeMode)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change Volume Compute Mode");
                        variation.randomVolumeMode = newMode;
                    }

                    var volMin = 0f;
                    if (variation.randomVolumeMode == SoundGroupVariation.RandomVolumeMode.AddToClipVolume)
                    {
                        volMin = -1f;
                    }

                    var newVolMin = EditorGUILayout.Slider("Random Volume Min", variation.randomVolumeMin, volMin, 1f);
                    if (newVolMin != variation.randomVolumeMin)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change Random Volume Min");
                        variation.randomVolumeMin = newVolMin;
                        if (variation.randomVolumeMax <= variation.randomVolumeMin)
                        {
                            variation.randomVolumeMax = variation.randomVolumeMin;
                        }
                    }

                    var newVolMax = EditorGUILayout.Slider("Random Volume Max", variation.randomVolumeMax, volMin, 1f);
                    if (newVolMax != variation.randomVolumeMax)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change Random Volume Max");
                        variation.randomVolumeMax = newVolMax;
                        if (variation.randomVolumeMin > variation.randomVolumeMax)
                        {
                            variation.randomVolumeMin = variation.randomVolumeMax;
                        }
                    }
                }

                EditorGUILayout.EndToggleGroup();

                var newSilence = EditorGUILayout.BeginToggleGroup("Use Random Delay", variation.useIntroSilence);
                if (newSilence != variation.useIntroSilence)
                {
                    UndoHelper.RecordObjectPropertyForUndo(variation, "toggle Use Random Delay");
                    variation.useIntroSilence = newSilence;
                }

                if (variation.useIntroSilence)
                {
                    var newSilenceMin = EditorGUILayout.Slider("Delay Min (sec)", variation.introSilenceMin, 0f, 100f);
                    if (newSilenceMin != variation.introSilenceMin)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change Delay Min (sec)");
                        variation.introSilenceMin = newSilenceMin;
                        if (variation.introSilenceMin > variation.introSilenceMax)
                        {
                            variation.introSilenceMax = newSilenceMin;
                        }
                    }

                    var newSilenceMax = EditorGUILayout.Slider("Delay Max (sec)", variation.introSilenceMax, 0f, 100f);
                    if (newSilenceMax != variation.introSilenceMax)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change Delay Max (sec)");
                        variation.introSilenceMax = newSilenceMax;
                        if (variation.introSilenceMax < variation.introSilenceMin)
                        {
                            variation.introSilenceMin = newSilenceMax;
                        }
                    }
                }

                EditorGUILayout.EndToggleGroup();

                var newFades = EditorGUILayout.BeginToggleGroup("Use Custom Fading", variation.useFades);
                if (newFades != variation.useFades)
                {
                    UndoHelper.RecordObjectPropertyForUndo(variation, "toggle Use Custom Fading");
                    variation.useFades = newFades;
                }

                if (variation.useFades)
                {
                    var newFadeIn = EditorGUILayout.Slider("Fade In Time (sec)", variation.fadeInTime, 0f, 10f);
                    if (newFadeIn != variation.fadeInTime)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change Fade In Time");
                        variation.fadeInTime = newFadeIn;
                    }

                    var newFadeOut = EditorGUILayout.Slider("Fade Out time (sec)", variation.fadeOutTime, 0f, 10f);
                    if (newFadeOut != variation.fadeOutTime)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(variation, "change Fade Out Time");
                        variation.fadeOutTime = newFadeOut;
                    }
                }
                EditorGUILayout.EndToggleGroup();

                EditorGUILayout.Separator();
            }
        }

        if (deadChildIndex.HasValue)
        {
            var deadVar = _group.groupVariations[deadChildIndex.Value];

            if (deadVar != null)
            {
                // delete variation from Hierarchy
                UndoHelper.DestroyForUndo(deadVar.gameObject);
            }

            // delete group.
            _group.groupVariations.RemoveAt(deadChildIndex.Value);
        }



        if (GUI.changed || isDirty)
        {
            EditorUtility.SetDirty(target);
        }

        //DrawDefaultInspector();
    }
Exemplo n.º 2
0
 // ReSharper disable once SuggestBaseTypeForParameter
 private static void RemoveStat(Transform stat)
 {
     UndoHelper.DestroyForUndo(stat.gameObject);
 }
    public override void OnInspectorGUI()
    {
        EditorGUIUtility.LookLikeControls();

        EditorGUI.indentLevel = 1;
        var isDirty = false;

        _creator = (DynamicSoundGroupCreator)target;

        var isInProjectView = DTGUIHelper.IsPrefabInProjectView(_creator);

        if (MasterAudioInspectorResources.logoTexture != null)
        {
            DTGUIHelper.ShowHeaderTexture(MasterAudioInspectorResources.logoTexture);
        }

        MasterAudio.Instance = null;
        MasterAudio ma = MasterAudio.Instance;

        var busVoiceLimitList = new List <string>();

        busVoiceLimitList.Add(MasterAudio.NO_VOICE_LIMIT_NAME);

        for (var i = 1; i <= 32; i++)
        {
            busVoiceLimitList.Add(i.ToString());
        }

        var busList = new List <string>();

        busList.Add(MasterAudioGroup.NO_BUS);
        busList.Add(MasterAudioInspector.NEW_BUS_NAME);
        busList.Add(EXISTING_BUS);

        int maxChars = 12;

        GroupBus bus = null;

        for (var i = 0; i < _creator.groupBuses.Count; i++)
        {
            bus = _creator.groupBuses[i];
            busList.Add(bus.busName);

            if (bus.busName.Length > maxChars)
            {
                maxChars = bus.busName.Length;
            }
        }
        var busListWidth = 9 * maxChars;

        EditorGUI.indentLevel = 0;  // Space will handle this for the header

        var newAwake = EditorGUILayout.Toggle("Auto-create Items", _creator.createOnAwake);

        if (newAwake != _creator.createOnAwake)
        {
            UndoHelper.RecordObjectPropertyForUndo(_creator, "toggle Auto-create Items");
            _creator.createOnAwake = newAwake;
        }
        if (_creator.createOnAwake)
        {
            DTGUIHelper.ShowColorWarning("*Items will be created as soon as this object is in the Scene.");
        }
        else
        {
            DTGUIHelper.ShowColorWarning("*You will need to call this object's CreateItems method.");
        }

        var newRemove = EditorGUILayout.Toggle("Auto-remove Items", _creator.removeGroupsOnSceneChange);

        if (newRemove != _creator.removeGroupsOnSceneChange)
        {
            UndoHelper.RecordObjectPropertyForUndo(_creator, "toggle Auto-remove Items");
            _creator.removeGroupsOnSceneChange = newRemove;
        }

        if (_creator.removeGroupsOnSceneChange)
        {
            DTGUIHelper.ShowColorWarning("*Items will be deleted when the Scene changes.");
        }
        else
        {
            DTGUIHelper.ShowColorWarning("*Items will persist across Scenes if MasterAudio does.");
        }

        EditorGUILayout.Separator();

        _groups = ScanForGroups();
        var groupNameList = GroupNameList;

        EditorGUI.indentLevel = 0;
        GUI.color             = _creator.showMusicDucking ? MasterAudioInspector.activeClr : MasterAudioInspector.inactiveClr;
        EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);

        var newShowDuck = EditorGUILayout.Toggle("Dynamic Music Ducking", _creator.showMusicDucking);

        if (newShowDuck != _creator.showMusicDucking)
        {
            UndoHelper.RecordObjectPropertyForUndo(_creator, "toggle Dynamic Music Ducking");
            _creator.showMusicDucking = newShowDuck;
        }
        EditorGUILayout.EndHorizontal();
        GUI.color = Color.white;

        if (_creator.showMusicDucking)
        {
            GUI.contentColor = Color.green;
            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(10);

            if (GUILayout.Button(new GUIContent("Add Duck Group"), EditorStyles.toolbarButton, GUILayout.Width(100)))
            {
                UndoHelper.RecordObjectPropertyForUndo(_creator, "Add Duck Group");

                var defaultBeginUnduck = 0.5f;
                if (ma != null)
                {
                    defaultBeginUnduck = ma.defaultRiseVolStart;
                }

                _creator.musicDuckingSounds.Add(new DuckGroupInfo()
                {
                    soundType    = MasterAudio.NO_GROUP_NAME,
                    riseVolStart = defaultBeginUnduck
                });
            }

            EditorGUILayout.EndHorizontal();
            GUI.contentColor = Color.white;
            EditorGUILayout.Separator();

            if (_creator.musicDuckingSounds.Count == 0)
            {
                DTGUIHelper.ShowColorWarning("*You currently have no ducking sounds set up.");
            }
            else
            {
                int?duckSoundToRemove = null;

                for (var i = 0; i < _creator.musicDuckingSounds.Count; i++)
                {
                    var duckSound = _creator.musicDuckingSounds[i];
                    var index     = groupNameList.IndexOf(duckSound.soundType);
                    if (index == -1)
                    {
                        index = 0;
                    }

                    EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                    var newIndex = EditorGUILayout.Popup(index, groupNameList.ToArray(), GUILayout.MaxWidth(200));
                    if (newIndex >= 0)
                    {
                        if (index != newIndex)
                        {
                            UndoHelper.RecordObjectPropertyForUndo(_creator, "change Duck Group");
                        }
                        duckSound.soundType = groupNameList[newIndex];
                    }

                    GUI.contentColor = Color.green;
                    GUILayout.TextField("Begin Unduck " + duckSound.riseVolStart.ToString("N2"), 20, EditorStyles.miniLabel);

                    var newUnduck = GUILayout.HorizontalSlider(duckSound.riseVolStart, 0f, 1f, GUILayout.Width(60));
                    if (newUnduck != duckSound.riseVolStart)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(_creator, "change Begin Unduck");
                        duckSound.riseVolStart = newUnduck;
                    }
                    GUI.contentColor = Color.white;

                    GUILayout.FlexibleSpace();
                    GUILayout.Space(10);
                    if (DTGUIHelper.AddDeleteIcon("Duck Sound"))
                    {
                        duckSoundToRemove = i;
                    }

                    EditorGUILayout.EndHorizontal();
                }

                if (duckSoundToRemove.HasValue)
                {
                    UndoHelper.RecordObjectPropertyForUndo(_creator, "delete Duck Group");
                    _creator.musicDuckingSounds.RemoveAt(duckSoundToRemove.Value);
                }
            }
        }

        EditorGUILayout.Separator();

        GUI.color = _creator.soundGroupsAreExpanded ? MasterAudioInspector.activeClr : MasterAudioInspector.inactiveClr;

        EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
        var newGroupEx = EditorGUILayout.Toggle("Dynamic Group Mixer", _creator.soundGroupsAreExpanded);

        if (newGroupEx != _creator.soundGroupsAreExpanded)
        {
            UndoHelper.RecordObjectPropertyForUndo(_creator, "toggle Dynamic Group Mixer");
            _creator.soundGroupsAreExpanded = newGroupEx;
        }

        EditorGUILayout.EndHorizontal();
        GUI.color = Color.white;

        if (_creator.soundGroupsAreExpanded)
        {
            var newDragMode = (MasterAudio.DragGroupMode)EditorGUILayout.EnumPopup("Bulk Creation Mode", _creator.curDragGroupMode);
            if (newDragMode != _creator.curDragGroupMode)
            {
                UndoHelper.RecordObjectPropertyForUndo(_creator, "change Bulk Creation Mode");
                _creator.curDragGroupMode = newDragMode;
            }

            var bulkMode = (MasterAudio.AudioLocation)EditorGUILayout.EnumPopup("Variation Create Mode", _creator.bulkVariationMode);
            if (bulkMode != _creator.bulkVariationMode)
            {
                UndoHelper.RecordObjectPropertyForUndo(_creator, "change Variation Mode");
                _creator.bulkVariationMode = bulkMode;
            }

            // create groups start
            EditorGUILayout.BeginVertical();
            var aEvent = Event.current;

            if (isInProjectView)
            {
                DTGUIHelper.ShowLargeBarAlert("*You are in Project View and cannot create or navigate Groups.");
                DTGUIHelper.ShowLargeBarAlert("*Pull this prefab into the Scene to create Groups.");
            }
            else
            {
                GUI.color = Color.yellow;

                var dragAreaGroup = GUILayoutUtility.GetRect(0f, 35f, GUILayout.ExpandWidth(true));
                GUI.Box(dragAreaGroup, "Drag Audio clips here to create groups!");

                GUI.color = Color.white;

                switch (aEvent.type)
                {
                case EventType.DragUpdated:
                case EventType.DragPerform:
                    if (!dragAreaGroup.Contains(aEvent.mousePosition))
                    {
                        break;
                    }

                    DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                    if (aEvent.type == EventType.DragPerform)
                    {
                        DragAndDrop.AcceptDrag();

                        Transform groupInfo = null;

                        var clips = new List <AudioClip>();

                        foreach (var dragged in DragAndDrop.objectReferences)
                        {
                            var aClip = dragged as AudioClip;
                            if (aClip == null)
                            {
                                continue;
                            }

                            clips.Add(aClip);
                        }

                        clips.Sort(delegate(AudioClip x, AudioClip y)
                        {
                            return(x.name.CompareTo(y.name));
                        });

                        for (var i = 0; i < clips.Count; i++)
                        {
                            var aClip = clips[i];
                            if (_creator.curDragGroupMode == MasterAudio.DragGroupMode.OneGroupPerClip)
                            {
                                CreateGroup(aClip);
                            }
                            else
                            {
                                if (groupInfo == null)
                                {         // one group with variations
                                    groupInfo = CreateGroup(aClip);
                                }
                                else
                                {
                                    CreateVariation(groupInfo, aClip);
                                }
                            }

                            isDirty = true;
                        }
                    }
                    Event.current.Use();
                    break;
                }
            }
            EditorGUILayout.EndVertical();
            // create groups end

            if (_creator.soundGroupsToCreate.Count > 0 && !Application.isPlaying)
            {
                if (isInProjectView)
                {
                    DTGUIHelper.ShowLargeBarAlert("You have data in an old format. Pull this prefab into the Scene, then Upgrade Data.");
                }
                else
                {
                    DTGUIHelper.ShowRedError("You have data in an old format. It will not be used as is.");
                    DTGUIHelper.ShowRedError("Upgrade it to the new format by clicking the Upgrade button below.");

                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Space(154);
                    GUI.contentColor = Color.green;
                    if (GUILayout.Button("Upgrade Data", EditorStyles.toolbarButton, GUILayout.Width(150)))
                    {
                        UpgradeData();
                    }
                    GUI.contentColor = Color.white;
                    EditorGUILayout.EndHorizontal();
                }
            }

            if (_groups.Count == 0)
            {
                DTGUIHelper.ShowColorWarning("*You currently have no Dynamic Sound Groups created.");
            }

            int?indexToDelete = null;

            EditorGUILayout.LabelField("Group Control", EditorStyles.miniBoldLabel);
            GUI.color = Color.white;
            int? busToCreate   = null;
            bool isExistingBus = false;

            for (var i = 0; i < _groups.Count; i++)
            {
                var aGroup = _groups[i];

                EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                GUILayout.Label(aGroup.name, GUILayout.Width(150));

                GUILayout.FlexibleSpace();

                // find bus.
                var selectedBusIndex = aGroup.busIndex == -1 ? 0 : aGroup.busIndex;

                GUI.contentColor = Color.white;
                GUI.color        = Color.cyan;

                var busIndex = EditorGUILayout.Popup("", selectedBusIndex, busList.ToArray(), GUILayout.Width(busListWidth));
                if (busIndex == -1)
                {
                    busIndex = 0;
                }

                if (aGroup.busIndex != busIndex && busIndex != 1)
                {
                    UndoHelper.RecordObjectPropertyForUndo(aGroup, "change Group Bus");
                }

                if (busIndex != 1)                   // don't change the index, so undo will work.
                {
                    aGroup.busIndex = busIndex;
                }

                GUI.color = Color.white;

                if (selectedBusIndex != busIndex)
                {
                    if (busIndex == 1 || busIndex == 2)
                    {
                        busToCreate = i;

                        isExistingBus = busIndex == 2;
                    }
                    else if (busIndex >= DynamicSoundGroupCreator.HardCodedBusOptions)
                    {
                        //GroupBus newBus = _creator.groupBuses[busIndex - MasterAudio.HARD_CODED_BUS_OPTIONS];
                        // do nothing unless we add muting and soloing here.
                    }
                }

                GUI.contentColor = Color.green;
                GUILayout.TextField("V " + aGroup.groupMasterVolume.ToString("N2"), 6, EditorStyles.miniLabel);

                var newVol = GUILayout.HorizontalSlider(aGroup.groupMasterVolume, 0f, 1f, GUILayout.Width(100));
                if (newVol != aGroup.groupMasterVolume)
                {
                    UndoHelper.RecordObjectPropertyForUndo(aGroup, "change Group Volume");
                    aGroup.groupMasterVolume = newVol;
                }

                GUI.contentColor = Color.white;

                var buttonPressed = DTGUIHelper.AddDynamicGroupButtons();
                EditorGUILayout.EndHorizontal();

                switch (buttonPressed)
                {
                case DTGUIHelper.DTFunctionButtons.Go:
                    Selection.activeGameObject = aGroup.gameObject;
                    break;

                case DTGUIHelper.DTFunctionButtons.Remove:
                    indexToDelete = i;
                    break;

                case DTGUIHelper.DTFunctionButtons.Play:
                    PreviewGroup(aGroup);
                    break;

                case DTGUIHelper.DTFunctionButtons.Stop:
                    StopPreviewingGroup();
                    break;
                }
            }

            if (busToCreate.HasValue)
            {
                CreateBus(busToCreate.Value, isExistingBus);
            }

            if (indexToDelete.HasValue)
            {
                UndoHelper.DestroyForUndo(_groups[indexToDelete.Value].gameObject);
            }

            EditorGUILayout.Separator();
            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(6);

            GUI.contentColor = Color.green;
            if (GUILayout.Button(new GUIContent("Max Group Volumes", "Reset all group volumes to full"), EditorStyles.toolbarButton, GUILayout.Width(120)))
            {
                UndoHelper.RecordObjectsForUndo(_groups.ToArray(), "Max Group Volumes");

                for (var l = 0; l < _groups.Count; l++)
                {
                    var aGroup = _groups[l];
                    aGroup.groupMasterVolume = 1f;
                }
            }
            GUI.contentColor = Color.white;
            EditorGUILayout.EndHorizontal();

            //buses
            if (_creator.groupBuses.Count > 0)
            {
                EditorGUILayout.Separator();
                EditorGUILayout.LabelField("Bus Control", EditorStyles.miniBoldLabel);

                GroupBus aBus        = null;
                int?     busToDelete = null;

                for (var i = 0; i < _creator.groupBuses.Count; i++)
                {
                    aBus = _creator.groupBuses[i];

                    EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);

                    var newBusName = EditorGUILayout.TextField("", aBus.busName, GUILayout.MaxWidth(200));
                    if (newBusName != aBus.busName)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(_creator, "change Bus Name");
                        aBus.busName = newBusName;
                    }

                    GUILayout.FlexibleSpace();

                    if (!aBus.isExisting)
                    {
                        GUILayout.Label("Voices");
                        GUI.color = Color.cyan;

                        var oldLimitIndex = busVoiceLimitList.IndexOf(aBus.voiceLimit.ToString());
                        if (oldLimitIndex == -1)
                        {
                            oldLimitIndex = 0;
                        }
                        var busVoiceLimitIndex = EditorGUILayout.Popup("", oldLimitIndex, busVoiceLimitList.ToArray(), GUILayout.MaxWidth(70));
                        if (busVoiceLimitIndex != oldLimitIndex)
                        {
                            UndoHelper.RecordObjectPropertyForUndo(_creator, "change Bus Voice Limit");
                            aBus.voiceLimit = busVoiceLimitIndex <= 0 ? -1 : busVoiceLimitIndex;
                        }

                        GUI.color = Color.white;

                        EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(50));
                        GUILayout.TextField("V " + aBus.volume.ToString("N2"), 6, EditorStyles.miniLabel);
                        EditorGUILayout.EndHorizontal();

                        var newBusVol = GUILayout.HorizontalSlider(aBus.volume, 0f, 1f, GUILayout.Width(86));
                        if (newBusVol != aBus.volume)
                        {
                            UndoHelper.RecordObjectPropertyForUndo(_creator, "change Bus Volume");
                            aBus.volume = newBusVol;
                        }

                        GUI.contentColor = Color.white;
                    }
                    else
                    {
                        DTGUIHelper.ShowColorWarning("Existing bus. No control.");
                    }

                    if (DTGUIHelper.AddDeleteIcon("Bus"))
                    {
                        busToDelete = i;
                    }

                    EditorGUILayout.EndHorizontal();
                }

                if (busToDelete.HasValue)
                {
                    DeleteBus(busToDelete.Value);
                }
            }
        }

        EditorGUILayout.Separator();
        // Show Custom Events
        GUI.color = _creator.showCustomEvents ? MasterAudioInspector.activeClr : MasterAudioInspector.inactiveClr;

        EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
        var newShowEvents = EditorGUILayout.Toggle("Dynamic Custom Events", _creator.showCustomEvents);

        if (_creator.showCustomEvents != newShowEvents)
        {
            UndoHelper.RecordObjectPropertyForUndo(_creator, "toggle Dynamic Custom Events");
            _creator.showCustomEvents = newShowEvents;
        }

        EditorGUILayout.EndHorizontal();
        GUI.color = Color.white;

        if (_creator.showCustomEvents)
        {
            var newEvent = EditorGUILayout.TextField("New Event Name", _creator.newEventName);
            if (newEvent != _creator.newEventName)
            {
                UndoHelper.RecordObjectPropertyForUndo(_creator, "change New Event Name");
                _creator.newEventName = newEvent;
            }

            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(154);
            GUI.contentColor = Color.green;
            if (GUILayout.Button("Create New Event", EditorStyles.toolbarButton, GUILayout.Width(100)))
            {
                CreateCustomEvent(_creator.newEventName);
            }
            GUI.contentColor = Color.white;
            EditorGUILayout.EndHorizontal();

            if (_creator.customEventsToCreate.Count == 0)
            {
                DTGUIHelper.ShowColorWarning("*You currently have no custom events defined here.");
            }

            EditorGUILayout.Separator();

            int?indexToDelete = null;
            int?indexToRename = null;

            for (var i = 0; i < _creator.customEventsToCreate.Count; i++)
            {
                var anEvent = _creator.customEventsToCreate[i];
                EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                GUILayout.Label(anEvent.EventName, GUILayout.Width(170));

                GUILayout.FlexibleSpace();

                var newName = GUILayout.TextField(anEvent.ProspectiveName, GUILayout.Width(170));
                if (newName != anEvent.ProspectiveName)
                {
                    UndoHelper.RecordObjectPropertyForUndo(_creator, "change Proposed Event Name");
                    anEvent.ProspectiveName = newName;
                }
                var buttonPressed = DTGUIHelper.AddCustomEventDeleteIcon(true);

                switch (buttonPressed)
                {
                case DTGUIHelper.DTFunctionButtons.Remove:
                    indexToDelete = i;
                    break;

                case DTGUIHelper.DTFunctionButtons.Rename:
                    indexToRename = i;
                    break;
                }

                EditorGUILayout.EndHorizontal();
            }

            if (indexToDelete.HasValue)
            {
                _creator.customEventsToCreate.RemoveAt(indexToDelete.Value);
            }
            if (indexToRename.HasValue)
            {
                RenameEvent(_creator.customEventsToCreate[indexToRename.Value]);
            }
        }

        // End Show Custom Events

        if (GUI.changed || isDirty)
        {
            EditorUtility.SetDirty(target);
        }

        this.Repaint();

        //DrawDefaultInspector();
    }