void Awake()
    {
        this.useGUILayout = false;
        duckingMode = AudioDuckingMode.NotDucking;
        currentSong = null;

        var audios = this.GetComponents<AudioSource>();
        if (audios.Length < 2)
        {
            Debug.LogError("This prefab should have exactly two Audio Source components. Please revert it.");
            return;
        }

        AudioSource audio1 = audios[0];
        AudioSource audio2 = audios[1];

        audio1.clip = null;
        audio2.clip = null;

        activeAudio = audio1;
        transitioningAudio = audio2;
        go = this.gameObject;
        curFadeMode = FadeMode.None;
        fadeCompleteCallback = null;
    }
    private bool SongShouldLoop(MusicSetting setting)
    {
        if (queuedSongs.Count > 0)
        {
            return(false);
        }

        if (CurrentPlaylist != null && CurrentPlaylist.songTransitionType == MasterAudio.SongFadeInPosition.SynchronizeClips)
        {
            return(true);
        }

        return(setting.isLoop);
    }
Exemplo n.º 3
0
    /// <summary>
    /// This method will Stop the Playlist.
    /// </summary>
    public void StopPlaylist(bool onlyFadingClip = false)
    {
        if (!Application.isPlaying)
        {
            return;
        }

        currentSong = null;
        if (!onlyFadingClip)
        {
            CeaseAudioSource(this.activeAudio);
        }

        CeaseAudioSource(this.transitioningAudio);
    }
    void Awake()
    {
        // check for "extra" Playlist Controllers of the same name.
        var controllers   = (PlaylistController[])GameObject.FindObjectsOfType(typeof(PlaylistController));
        var sameNameCount = 0;

        for (var i = 0; i < controllers.Length; i++)
        {
            if (controllers[i].gameObject.name == gameObject.name)
            {
                sameNameCount++;
            }
        }

        if (sameNameCount > 1)
        {
            Destroy(gameObject);
            Debug.Log("More than one Playlist Controller prefab exists in this Scene with the same name. Destroying the one called '" + this.name + "'. You may wish to set up a Bootstrapper Scene so this does not occur.");
            return;
        }
        // end check

        this.useGUILayout       = false;
        duckingMode             = AudioDuckingMode.NotDucking;
        currentSong             = null;
        songsPlayedFromPlaylist = 0;

        var audios = this.GetComponents <AudioSource>();

        if (audios.Length < 2)
        {
            Debug.LogError("This prefab should have exactly two Audio Source components. Please revert it.");
            return;
        }

        AudioSource audio1 = audios[0];
        AudioSource audio2 = audios[1];

        audio1.clip = null;
        audio2.clip = null;

        activeAudio        = audio1;
        transitioningAudio = audio2;
        go                   = this.gameObject;
        curFadeMode          = FadeMode.None;
        fadeCompleteCallback = null;
        lostFocus            = false;
    }
    private void FillClips()
    {
        clipsRemaining.Clear();

        // add clips from named playlist.
        if (startPlaylistName == MasterAudio.NO_PLAYLIST_NAME)
        {
            return;
        }

        this.currentPlaylist = MasterAudio.GrabPlaylist(startPlaylistName);

        if (this.currentPlaylist == null)
        {
            return;
        }

        MusicSetting aSong = null;

        for (var i = 0; i < currentPlaylist.MusicSettings.Count; i++)
        {
            aSong           = currentPlaylist.MusicSettings[i];
            aSong.songIndex = i;

            if (aSong.audLocation != MasterAudio.AudioLocation.ResourceFile)
            {
                if (aSong.clip == null)
                {
                    continue;
                }
            }
            else
            { // resource file!
                if (string.IsNullOrEmpty(aSong.resourceFileName))
                {
                    continue;
                }
            }

            clipsRemaining.Add(i);
        }
    }
Exemplo n.º 6
0
 void playCorrectMusic(MusicSetting musicSetting)
 {
     if (musicSetting == MusicSetting.Audio1)
     {
         BGM1();
     }
     else if (musicSetting == MusicSetting.Audio2)
     {
         BGM2();
     }
     else if (musicSetting == MusicSetting.NoMusic)
     {
         turnOffAudio();
     }
     else
     {
         Debug.Log("Error");
         Debug.Log(musicSetting);
     }
 }
Exemplo n.º 7
0
    /// <summary>
    /// This method will play the song in the current Playlist whose name you specify as soon as the currently playing song is done. The current song, if looping, will have loop turned off by this call. This requires auto-advance to work.
    /// </summary>
    /// <param name="clipName">The name of the song to play.</param>
    public void QueuePlaylistClip(string clipName)
    {
        if (currentPlaylist == null)
        {
            MasterAudio.LogNoPlaylist(this.name, "QueuePlaylistClip");
            return;
        }

        if (!this.activeAudio.isPlaying)
        {
            TriggerPlaylistClip(clipName);
            return;
        }

        MusicSetting setting = currentPlaylist.MusicSettings.Find(delegate(MusicSetting obj)
        {
            if (obj.audLocation == MasterAudio.AudioLocation.Clip)
            {
                return(obj.clip != null && obj.clip.name == clipName);
            }
            else
            { // resource file!
                return(obj.resourceFileName == clipName);
            }
        });

        if (setting == null)
        {
            Debug.LogWarning("Could not find clip '" + clipName + "' in current Playlist in '" + this.name + "'.");
            return;
        }

        // turn off loop if it's on.
        this.activeAudio.loop = false;
        // add to queue.
        queuedSongs.Add(setting);
    }
Exemplo n.º 8
0
    /// <summary>
    /// This method will allow you to add a song to a Playlist by code.
    /// </summary>
    /// <param name="playlistName">The name of the Playlist to add the song to.</param>
    /// <param name="song">The Audio clip of the song.</param>
    /// <param name="loopSong">Optional - whether or not to loop the song.</param>
    /// <param name="songPitch">Optional - the pitch of the song.</param>
    /// <param name="songVolume">Optional - The volume of the song.</param>
    public static void AddSongToPlaylist(string playlistName, AudioClip song, bool loopSong = false, float songPitch = 1f, float songVolume = 1f)
    {
        var pl = GrabPlaylist(playlistName);

        if (pl == null)
        {
            return;
        }

        var newSong = new MusicSetting()
        {
            clip = song,
            isExpanded = true,
            isLoop = loopSong,
            pitch = songPitch,
            volume = songVolume
        };

        pl.MusicSettings.Add(newSong);
    }
    private void AddSongToPlaylist(MasterAudio.Playlist pList, AudioClip aClip) {
        MusicSetting lastClip = null;
        if (pList.MusicSettings.Count > 0) {
            lastClip = pList.MusicSettings[pList.MusicSettings.Count - 1];
        }

        MusicSetting mus;

        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "add Song");

        if (lastClip != null && lastClip.clip == null && pList.bulkLocationMode == MasterAudio.AudioLocation.Clip) {
            mus = lastClip;
            mus.clip = aClip;
        } else if (lastClip != null && string.IsNullOrEmpty(lastClip.resourceFileName) && pList.bulkLocationMode == MasterAudio.AudioLocation.ResourceFile) {
            mus = lastClip;
            var unused = false;
            var resourceFileName = DTGUIHelper.GetResourcePath(aClip, ref unused);
            if (string.IsNullOrEmpty(resourceFileName)) {
                // ReSharper disable once RedundantAssignment
                resourceFileName = aClip.name;
            } else {
                mus.resourceFileName = resourceFileName;
            }
        } else {
            mus = new MusicSetting() {
                volume = 1f,
                pitch = 1f,
                isExpanded = true,
                audLocation = pList.bulkLocationMode
            };

            switch (pList.bulkLocationMode) {
                case MasterAudio.AudioLocation.Clip:
                    mus.clip = aClip;
                    if (aClip != null) {
                        mus.songName = aClip.name;
                    }
                    break;
                case MasterAudio.AudioLocation.ResourceFile:
                    var unused = false;
                    var resourceFileName = DTGUIHelper.GetResourcePath(aClip, ref unused);
                    if (string.IsNullOrEmpty(resourceFileName)) {
                        resourceFileName = aClip.name;
                    }

                    mus.clip = null;
                    mus.resourceFileName = resourceFileName;
                    mus.songName = aClip.name;
                    break;
            }

            pList.MusicSettings.Add(mus);
        }
    }
Exemplo n.º 10
0
    public void FinishLoadingNewSong(AudioClip clipToPlay)
    {
        nextSongRequested = false;
        audioClip.clip = clipToPlay;
        audioClip.pitch = newSongSetting.pitch;

        // set last known time for current song.
        if (currentSong != null) {
            currentSong.lastKnownTimePoint = activeAudio.timeSamples;
        }

        if (CrossFadeTime == 0 || transClip.clip == null) {
            CeaseAudioSource(transClip);
            audioClip.volume = newSongSetting.volume * PlaylistVolume;

            if (!ActiveAudioSource.isPlaying && currentPlaylist != null && currentPlaylist.fadeInFirstSong) {
                CrossFadeNow(audioClip);
            }
        } else {
            CrossFadeNow(audioClip);
        }

        SetDuckProperties();

        audioClip.Play(); // need to play before setting time or it sometimes resets back to zero.
        songsPlayedFromPlaylist++;

        var songTimeChanged = false;

        if (syncGroupNum > 0 && currentPlaylist.songTransitionType == MasterAudio.SongFadeInPosition.SynchronizeClips) {
            var firstMatchingGroupController = PlaylistController.Instances.Find(delegate(PlaylistController obj) {
                return obj != this && obj.syncGroupNum == syncGroupNum && obj.ActiveAudioSource.isPlaying;
            });

            if (firstMatchingGroupController != null) {
                audioClip.timeSamples = firstMatchingGroupController.activeAudio.timeSamples;
                songTimeChanged = true;
            }
        }

        // this code will adjust the starting position of a song, but shouldn't do so when you first change Playlists.
        if (currentPlaylist != null) {
            if (songsPlayedFromPlaylist <= 1 && !songTimeChanged) {
                audioClip.timeSamples = 0; // reset pointer so a new Playlist always starts at the beginning, but don't do it for synchronized! We need that first song to use the sync group.
            } else {
                switch (currentPlaylist.songTransitionType) {
                    case MasterAudio.SongFadeInPosition.SynchronizeClips:
                        if (!songTimeChanged) { // otherwise the sync group code above will get defeated.
                            transitioningAudio.timeSamples = activeAudio.timeSamples;
                        }
                        break;
                    case MasterAudio.SongFadeInPosition.NewClipFromLastKnownPosition:
                        var thisSongInPlaylist = currentPlaylist.MusicSettings.Find(delegate(MusicSetting obj) {
                            return obj == newSongSetting;
                        });

                        if (thisSongInPlaylist != null) {
                            transitioningAudio.timeSamples = thisSongInPlaylist.lastKnownTimePoint;
                        }
                        break;
                    case MasterAudio.SongFadeInPosition.NewClipFromBeginning:
                        audioClip.timeSamples = 0; // new song will start at beginning
                        break;
                }
            }

            // account for custom start time.
            if (currentPlaylist.songTransitionType == MasterAudio.SongFadeInPosition.NewClipFromBeginning && newSongSetting.customStartTime > 0f) {
                audioClip.timeSamples = (int)(newSongSetting.customStartTime * audioClip.clip.frequency);
            }
        }

        activeAudio = audioClip;
        transitioningAudio = transClip;

        if (SongChanged != null) {
            var clipName = String.Empty;
            if (audioClip != null) {
                clipName = audioClip.clip.name;
            }
            SongChanged(clipName);
        }

        activeAudioEndVolume = newSongSetting.volume * PlaylistVolume;
        var transStartVol = transitioningAudio.volume;
        if (currentSong != null) {
            transStartVol = currentSong.volume;
        }

        transitioningAudioStartVolume = transStartVol * PlaylistVolume;
        currentSong = newSongSetting;
    }
Exemplo n.º 11
0
 public MusicPlaySettingMsg(MusicSetting musicSetting)
 {
     this.musicSetting = musicSetting;
 }
Exemplo n.º 12
0
    void Awake()
    {
        // check for "extra" Playlist Controllers of the same name.
        var controllers = (PlaylistController[]) GameObject.FindObjectsOfType(typeof(PlaylistController));
        var sameNameCount = 0;

        for (var i = 0; i < controllers.Length; i++) {
            if (controllers[i].gameObject.name == gameObject.name) {
                sameNameCount++;
            }
        }

        if (sameNameCount > 1) {
            Destroy(gameObject);
            Debug.Log("More than one Playlist Controller prefab exists in this Scene with the same name. Destroying the one called '" + this.name + "'. You may wish to set up a Bootstrapper Scene so this does not occur.");
            return;
        }
        // end check

        this.useGUILayout = false;
        duckingMode = AudioDuckingMode.NotDucking;
        currentSong = null;
        songsPlayedFromPlaylist = 0;

        var audios = this.GetComponents<AudioSource>();
        if (audios.Length < 2)
        {
            Debug.LogError("This prefab should have exactly two Audio Source components. Please revert it.");
            return;
        }

        AudioSource audio1 = audios[0];
        AudioSource audio2 = audios[1];

        audio1.clip = null;
        audio2.clip = null;

        activeAudio = audio1;
        transitioningAudio = audio2;
        go = this.gameObject;
        curFadeMode = FadeMode.None;
        fadeCompleteCallback = null;
    }
Exemplo n.º 13
0
    private bool SongShouldLoop(MusicSetting setting)
    {
        if (queuedSongs.Count > 0)
        {
            return false;
        }

        if (CurrentPlaylist != null && CurrentPlaylist.songTransitionType == MasterAudio.SongFadeInPosition.SynchronizeClips)
        {
            return true;
        }

        return setting.isLoop;
    }
        private async Task SendControlSettingEventActivityAsync(WaterfallStepContext stepContext, MusicSetting setting, CancellationToken cancellationToken = default(CancellationToken))
        {
            var replyEvent = stepContext.Context.Activity.CreateReply();

            replyEvent.Type  = ActivityTypes.Event;
            replyEvent.Name  = $"MusicSkill.{setting.Name}";
            replyEvent.Value = setting;
            await stepContext.Context.SendActivityAsync(replyEvent, cancellationToken);
        }
    private void PlayPlaylistSong(MusicSetting setting)
    {
        AudioSource audioClip;
        AudioSource transClip;

        if (activeAudio == null) {
            Debug.LogError("PlaylistController prefab is not in your scene. Cannot play a song.");
            return;
        }

        if (activeAudio.clip == null) {
            audioClip = activeAudio;
            transClip = transitioningAudio;
        } else if (transitioningAudio.clip == null) {
            audioClip = transitioningAudio;
            transClip = activeAudio;
        } else {
            // both are busy!
            //Debug.LogWarning("Both audio sources are busy cross-fading. You may want to shorten your cross-fade time in Playlist Inspector.");
            audioClip = transitioningAudio;
            transClip = activeAudio;
        }

        if (setting.clip != null) {
            audioClip.clip = setting.clip;
            audioClip.pitch = setting.pitch;
        }

        audioClip.loop = SongShouldLoop(setting);
        audioClip.clip = setting.clip;
        audioClip.pitch = setting.pitch;

        // set last know time for current song.
        if (currentSong != null) {
            currentSong.lastKnownTimePoint = activeAudio.timeSamples;
        }

        if (MasterAudio.Instance.CrossFadeTime == 0 || transClip.clip == null) {
            CeaseAudioSource(transClip);
            audioClip.volume = setting.volume * PlaylistVolume;
        } else {
            audioClip.volume = 0f;
            isCrossFading = true;
            duckingMode = AudioDuckingMode.NotDucking;
            crossFadeStartTime = Time.time;
        }

        SetDuckProperties();

        if (currentPlaylist != null) {
            switch (currentPlaylist.songTransitionType) {
                case MasterAudio.SongFadeInPosition.SynchronizeClips:
                    transitioningAudio.timeSamples = activeAudio.timeSamples;
                    break;
                case MasterAudio.SongFadeInPosition.NewClipFromLastKnownPosition:
                    var thisSongInPlaylist = currentPlaylist.MusicSettings.Find(delegate(MusicSetting obj) {
                        return obj == setting;
                    });

                    if (thisSongInPlaylist != null) {
                        transitioningAudio.timeSamples = thisSongInPlaylist.lastKnownTimePoint;
                    }
                    break;
            }
        }

        if (SongChanged != null) {
            var clipName = String.Empty;
            if (audioClip != null) {
                clipName = audioClip.clip.name;
            }
            SongChanged(clipName);
        }

        audioClip.Play();

        activeAudio = audioClip;
        transitioningAudio = transClip;

        activeAudioEndVolume = setting.volume * PlaylistVolume;
        transitioningAudioStartVolume = transitioningAudio.volume * PlaylistVolume;
        currentSong = setting;
    }
    /// <summary>
    /// This method will Stop the Playlist. Cross-fading will still happen (cross-fading to no new song).
    /// </summary>
    public void StopPlaylist()
    {
        if (!Application.isPlaying) {
            return;
        }

        currentSong = null;
        CeaseAudioSource(this.activeAudio);
        CeaseAudioSource(this.transitioningAudio);
    }
    private void AddSongToPlaylist(MasterAudio.Playlist pList, AudioClip aClip)
    {
        var lastClip = pList.MusicSettings[pList.MusicSettings.Count - 1];

        MusicSetting mus;

        UndoHelper.RecordObjectPropertyForUndo(sounds, "add Song");

        if (lastClip.clip == null) {
            mus = lastClip;
            mus.clip = aClip;
        } else {
            mus = new MusicSetting() {
                clip = aClip,
                volume = 1f,
                pitch = 1f,
                isExpanded = true
            };

            pList.MusicSettings.Add(mus);
        }
    }
    public override void OnInspectorGUI()
    {
        EditorGUIUtility.LookLikeControls();

        EditorGUI.indentLevel = 1;
        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 maInScene = ma != null;

        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

        if (MasterAudio.Instance == null) {
            var newLang = (SystemLanguage) EditorGUILayout.EnumPopup(new GUIContent("Preview Language", "This setting is only used (and visible) to choose the previewing language when there's no Master Audio prefab in the Scene (language settings are grabbed from there normally). This should only happen when you're using a Master Audio prefab from a previous Scene in persistent mode."), _creator.previewLanguage);
            if (newLang != _creator.previewLanguage) {
                UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Preview Language");
                _creator.previewLanguage = newLang;
            }
        }

        EditorGUILayout.Separator();

        var newAwake = EditorGUILayout.Toggle("Auto-create Items", _creator.createOnAwake);
        if (newAwake != _creator.createOnAwake) {
            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _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.ShowLargeBarAlert("You will need to call this object's CreateItems method manually to create the items.");
        }

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

        if (_creator.removeGroupsOnSceneChange) {
            DTGUIHelper.ShowColorWarning("*Items will be deleted when the Scene changes.");
        } else {
            DTGUIHelper.ShowLargeBarAlert("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(ref isDirty, _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(ref isDirty, _creator, "Add Duck Group");

                var defaultBeginUnduck = 0.5f;
                if (maInScene) {
                    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.ShowLargeBarAlert("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(ref isDirty, _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(ref isDirty, _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(ref isDirty, _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(ref isDirty, _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(ref isDirty, _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(ref isDirty, _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 (_groups.Count == 0) {
                DTGUIHelper.ShowLargeBarAlert("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];

                var groupDirty = false;

                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(ref groupDirty, 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(ref groupDirty, 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 (groupDirty) {
                    EditorUtility.SetDirty(aGroup);
                }
            }

            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();

                var oneVoiceBuses = _creator.groupBuses.FindAll(delegate(GroupBus obj) {
                    return obj.voiceLimit == 1;
                }).Count;

                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("Bus Control", EditorStyles.miniBoldLabel, GUILayout.Width(100));
                if (oneVoiceBuses > 0) {
                    GUILayout.FlexibleSpace();
                    GUILayout.Label("Dialog Mode", EditorStyles.miniBoldLabel, GUILayout.Width(100));
                    GUILayout.Space(230);
                }
                EditorGUILayout.EndHorizontal();

                GroupBus aBus = null;
                int? busToDelete = null;

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

                    EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);

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

                    GUILayout.FlexibleSpace();

                    if (!aBus.isExisting) {
                        if (aBus.voiceLimit == 1) {
                            GUI.color = Color.yellow;
                            var newMono = GUILayout.Toggle(aBus.isMonoBus, new GUIContent("", "Dialog Bus Mode"));
                            if (newMono != aBus.isMonoBus) {
                                UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "toggle Dialog Bus Mode");
                                aBus.isMonoBus = newMono;
                            }
                        }

                        GUI.color = Color.white;
                        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(ref isDirty, _creator, "change Bus Voice Limit");
                            aBus.voiceLimit = busVoiceLimitIndex <= 0 ? -1 : busVoiceLimitIndex;
                        }

                        GUI.color = Color.green;

                        GUILayout.TextField("V " + aBus.volume.ToString("N2"), 6, EditorStyles.miniLabel);

                        GUI.color = Color.white;
                        var newBusVol = GUILayout.HorizontalSlider(aBus.volume, 0f, 1f, GUILayout.Width(86));
                        if (newBusVol != aBus.volume) {
                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _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();
        // Music playlist Start
        EditorGUILayout.BeginHorizontal();
        EditorGUI.indentLevel = 0;  // Space will handle this for the header

        GUI.color = _creator.playListExpanded ? MasterAudioInspector.activeClr : MasterAudioInspector.inactiveClr;
        EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
        var isExp = EditorGUILayout.Toggle("Dynamic Playlist Settings", _creator.playListExpanded);
        if (isExp != _creator.playListExpanded) {
            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "toggle Dynamic Playlist Settings");
            _creator.playListExpanded = isExp;
        }

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

        EditorGUILayout.EndHorizontal();

        if (_creator.playListExpanded) {
            EditorGUI.indentLevel = 0;  // Space will handle this for the header

            if (_creator.musicPlaylists.Count == 0) {
                DTGUIHelper.ShowLargeBarAlert("You currently have no Playlists set up.");
            }

            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
            var oldPlayExpanded = DTGUIHelper.Foldout(_creator.playlistEditorExp, string.Format("Playlists ({0})", _creator.musicPlaylists.Count));
            if (oldPlayExpanded != _creator.playlistEditorExp) {
                UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "toggle Playlists");
                _creator.playlistEditorExp = oldPlayExpanded;
            }

            EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(100));

            GUIContent content;
            var buttonText = "Click to add new Playlist at the end";
            bool addPressed = false;

            // Add button - Process presses later
            GUI.contentColor = Color.green;
            addPressed = GUILayout.Button(new GUIContent("Add", buttonText),
                                               EditorStyles.toolbarButton);

            content = new GUIContent("Collapse", "Click to collapse all");
            var masterCollapse = GUILayout.Button(content, EditorStyles.toolbarButton);

            content = new GUIContent("Expand", "Click to expand all");
            var masterExpand = GUILayout.Button(content, EditorStyles.toolbarButton);
            if (masterExpand) {
                ExpandCollapseAllPlaylists(true);
            }
            if (masterCollapse) {
                ExpandCollapseAllPlaylists(false);
            }
            GUI.contentColor = Color.white;
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndHorizontal();

            if (_creator.playlistEditorExp) {
                int? playlistToRemove = null;
                int? playlistToInsertAt = null;
                int? playlistToMoveUp = null;
                int? playlistToMoveDown = null;

                for (var i = 0; i < _creator.musicPlaylists.Count; i++) {
                    EditorGUILayout.Separator();
                    var aList = _creator.musicPlaylists[i];

                    EditorGUI.indentLevel = 1;
                    EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
                    aList.isExpanded = DTGUIHelper.Foldout(aList.isExpanded, "Playlist: " + aList.playlistName);

                    var playlistButtonPressed = DTGUIHelper.AddFoldOutListItemButtons(i, _creator.musicPlaylists.Count, "playlist", false, true);

                    EditorGUILayout.EndHorizontal();

                    if (aList.isExpanded) {
                        EditorGUI.indentLevel = 0;
                        var newPlaylist = EditorGUILayout.TextField("Name", aList.playlistName);
                        if (newPlaylist != aList.playlistName) {
                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Name");
                            aList.playlistName = newPlaylist;
                        }

                        var crossfadeMode = (MasterAudio.Playlist.CrossfadeTimeMode)EditorGUILayout.EnumPopup("Crossfade Mode", aList.crossfadeMode);
                        if (crossfadeMode != aList.crossfadeMode) {
                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Crossfade Mode");
                            aList.crossfadeMode = crossfadeMode;
                        }
                        if (aList.crossfadeMode == MasterAudio.Playlist.CrossfadeTimeMode.Override) {
                            var newCF = EditorGUILayout.Slider("Crossfade time (sec)", aList.crossFadeTime, 0f, 10f);
                            if (newCF != aList.crossFadeTime) {
                                UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Crossfade time (sec)");
                                aList.crossFadeTime = newCF;
                            }
                        }

                        var newFadeIn = EditorGUILayout.Toggle("Fade In First Song", aList.fadeInFirstSong);
                        if (newFadeIn != aList.fadeInFirstSong) {
                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "toggle Fade In First Song");
                            aList.fadeInFirstSong = newFadeIn;
                        }

                        var newFadeOut = EditorGUILayout.Toggle("Fade Out Last Song", aList.fadeOutLastSong);
                        if (newFadeOut != aList.fadeOutLastSong) {
                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "toggle Fade Out Last Song");
                            aList.fadeOutLastSong = newFadeOut;
                        }

                        var newTransType = (MasterAudio.SongFadeInPosition)EditorGUILayout.EnumPopup("Song Transition Type", aList.songTransitionType);
                        if (newTransType != aList.songTransitionType) {
                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Song Transition Type");
                            aList.songTransitionType = newTransType;
                        }
                        if (aList.songTransitionType == MasterAudio.SongFadeInPosition.SynchronizeClips) {
                            DTGUIHelper.ShowColorWarning("*All clips must be of exactly the same length in this mode.");
                        }

                        EditorGUI.indentLevel = 0;
                        var newBulkMode = (MasterAudio.AudioLocation)EditorGUILayout.EnumPopup("Clip Create Mode", aList.bulkLocationMode);
                        if (newBulkMode != aList.bulkLocationMode) {
                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Bulk Clip Mode");
                            aList.bulkLocationMode = newBulkMode;
                        }

                        var playlistHasResource = false;
                        for (var s = 0; s < aList.MusicSettings.Count; s++) {
                            if (aList.MusicSettings[s].audLocation == MasterAudio.AudioLocation.ResourceFile) {
                                playlistHasResource = true;
                                break;
                            }
                        }

                        if (MasterAudio.HasAsyncResourceLoaderFeature() && playlistHasResource) {
                            if (!maInScene || !ma.resourceClipsAllLoadAsync) {
                                var newAsync = EditorGUILayout.Toggle(new GUIContent("Load Resources Async", "Checking this means Resource files in this Playlist will be loaded asynchronously."), aList.resourceClipsAllLoadAsync);
                                if (newAsync != aList.resourceClipsAllLoadAsync) {
                                    UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "toggle Load Resources Async");
                                    aList.resourceClipsAllLoadAsync = newAsync;
                                }
                            }
                        }
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.Space(10);
                        GUI.contentColor = Color.green;
                        if (GUILayout.Button(new GUIContent("Equalize Song Volumes"), EditorStyles.toolbarButton)) {
                            EqualizePlaylistVolumes(aList.MusicSettings);
                        }

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

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

                        GUI.color = Color.yellow;

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

                        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;
                                        }

                                        AddSongToPlaylist(aList, aClip);
                                    }
                                }
                                Event.current.Use();
                                break;
                        }
                        EditorGUILayout.EndVertical();

                        EditorGUI.indentLevel = 2;

                        int? addIndex = null;
                        int? removeIndex = null;
                        int? moveUpIndex = null;
                        int? moveDownIndex = null;

                        if (aList.MusicSettings.Count == 0) {
                            EditorGUI.indentLevel = 0;
                            DTGUIHelper.ShowLargeBarAlert("You currently have no songs in this Playlist.");
                        }

                        EditorGUI.indentLevel = 2;

                        for (var j = 0; j < aList.MusicSettings.Count; j++) {
                            var aSong = aList.MusicSettings[j];
                            var clipName = "Empty";
                            switch (aSong.audLocation) {
                                case MasterAudio.AudioLocation.Clip:
                                    if (aSong.clip != null) {
                                        clipName = aSong.clip.name;
                                    }
                                    break;
                                case MasterAudio.AudioLocation.ResourceFile:
                                    if (!string.IsNullOrEmpty(aSong.resourceFileName)) {
                                        clipName = aSong.resourceFileName;
                                    }
                                    break;
                            }
                            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                            EditorGUI.indentLevel = 2;

                            if (!string.IsNullOrEmpty(clipName) && string.IsNullOrEmpty(aSong.songName)) {
                                switch (aSong.audLocation) {
                                    case MasterAudio.AudioLocation.Clip:
                                        aSong.songName = clipName;
                                        break;
                                    case MasterAudio.AudioLocation.ResourceFile:
                                        aSong.songName = clipName;
                                        break;
                                }
                            }

                            var newSongExpanded = DTGUIHelper.Foldout(aSong.isExpanded, aSong.songName);
                            if (newSongExpanded != aSong.isExpanded) {
                                UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "toggle Song expand");
                                aSong.isExpanded = newSongExpanded;
                            }
                            var songButtonPressed = DTGUIHelper.AddFoldOutListItemButtons(j, aList.MusicSettings.Count, "clip", false, true, true);
                            EditorGUILayout.EndHorizontal();

                            if (aSong.isExpanded) {
                                EditorGUI.indentLevel = 0;

                                var oldLocation = aSong.audLocation;
                                var newClipSource = (MasterAudio.AudioLocation)EditorGUILayout.EnumPopup("Audio Origin", aSong.audLocation);
                                if (newClipSource != aSong.audLocation) {
                                    UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Audio Origin");
                                    aSong.audLocation = newClipSource;
                                }

                                switch (aSong.audLocation) {
                                    case MasterAudio.AudioLocation.Clip:
                                        var newClip = (AudioClip)EditorGUILayout.ObjectField("Audio Clip", aSong.clip, typeof(AudioClip), true);
                                        if (newClip != aSong.clip) {
                                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Clip");
                                            aSong.clip = newClip;
                                            var cName = newClip == null ? "Empty" : newClip.name;
                                            aSong.songName = cName;
                                        }
                                        break;
                                    case MasterAudio.AudioLocation.ResourceFile:
                                        if (oldLocation != aSong.audLocation) {
                                            if (aSong.clip != null) {
                                                Debug.Log("Audio clip removed to prevent unnecessary memory usage on Resource file Playlist clip.");
                                            }
                                            aSong.clip = null;
                                            aSong.songName = string.Empty;
                                        }

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

                                        GUI.color = Color.yellow;
                                        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(ref isDirty, _creator, "change Resource Filename");

                                                        var unused = false;
                                                        var resourceFileName = DTGUIHelper.GetResourcePath(aClip, ref unused);
                                                        if (string.IsNullOrEmpty(resourceFileName)) {
                                                            resourceFileName = aClip.name;
                                                        }

                                                        aSong.resourceFileName = resourceFileName;
                                                        aSong.songName = aClip.name;
                                                    }
                                                }
                                                Event.current.Use();
                                                break;
                                        }
                                        EditorGUILayout.EndVertical();

                                        var newFilename = EditorGUILayout.TextField("Resource Filename", aSong.resourceFileName);
                                        if (newFilename != aSong.resourceFileName) {
                                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Resource Filename");
                                            aSong.resourceFileName = newFilename;
                                        }

                                        break;
                                }

                                var newVol = EditorGUILayout.Slider("Volume", aSong.volume, 0f, 1f);
                                if (newVol != aSong.volume) {
                                    UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Volume");
                                    aSong.volume = newVol;
                                }

                                var newPitch = EditorGUILayout.Slider("Pitch", aSong.pitch, -3f, 3f);
                                if (newPitch != aSong.pitch) {
                                    UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Pitch");
                                    aSong.pitch = newPitch;
                                }

                                var newLoop = EditorGUILayout.Toggle("Loop Clip", aSong.isLoop);
                                if (newLoop != aSong.isLoop) {
                                    UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "toggle Loop Clip");
                                    aSong.isLoop = newLoop;
                                }
                            }

                            switch (songButtonPressed) {
                                case DTGUIHelper.DTFunctionButtons.Add:
                                    addIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.Remove:
                                    removeIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.ShiftUp:
                                    moveUpIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.ShiftDown:
                                    moveDownIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.Play:
                                    MasterAudio.PreviewerInstance.Stop();
                                    MasterAudio.PreviewerInstance.PlayOneShot(aSong.clip, aSong.volume);
                                    break;
                                case DTGUIHelper.DTFunctionButtons.Stop:
                                    MasterAudio.PreviewerInstance.clip = null;
                                    MasterAudio.PreviewerInstance.Stop();
                                    break;
                            }
                        }

                        if (addIndex.HasValue) {
                            var mus = new MusicSetting();
                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "add song");
                            aList.MusicSettings.Insert(addIndex.Value + 1, mus);
                        } else if (removeIndex.HasValue) {
                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "delete song");
                            aList.MusicSettings.RemoveAt(removeIndex.Value);
                        } else if (moveUpIndex.HasValue) {
                            var item = aList.MusicSettings[moveUpIndex.Value];

                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "shift up song");

                            aList.MusicSettings.Insert(moveUpIndex.Value - 1, item);
                            aList.MusicSettings.RemoveAt(moveUpIndex.Value + 1);
                        } else if (moveDownIndex.HasValue) {
                            var index = moveDownIndex.Value + 1;
                            var item = aList.MusicSettings[index];

                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "shift down song");

                            aList.MusicSettings.Insert(index - 1, item);
                            aList.MusicSettings.RemoveAt(index + 1);
                        }
                    }

                    switch (playlistButtonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            playlistToRemove = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Add:
                            playlistToInsertAt = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.ShiftUp:
                            playlistToMoveUp = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.ShiftDown:
                            playlistToMoveDown = i;
                            break;
                    }
                }

                if (playlistToRemove.HasValue) {
                    UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "delete Playlist");

                    _creator.musicPlaylists.RemoveAt(playlistToRemove.Value);
                }
                if (playlistToInsertAt.HasValue) {
                    var pl = new MasterAudio.Playlist();
                    UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "add Playlist");
                    _creator.musicPlaylists.Insert(playlistToInsertAt.Value + 1, pl);
                }
                if (playlistToMoveUp.HasValue) {
                    var item = _creator.musicPlaylists[playlistToMoveUp.Value];
                    UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "shift up Playlist");
                    _creator.musicPlaylists.Insert(playlistToMoveUp.Value - 1, item);
                    _creator.musicPlaylists.RemoveAt(playlistToMoveUp.Value + 1);
                }
                if (playlistToMoveDown.HasValue) {
                    var index = playlistToMoveDown.Value + 1;
                    var item = _creator.musicPlaylists[index];

                    UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "shift down Playlist");

                    _creator.musicPlaylists.Insert(index - 1, item);
                    _creator.musicPlaylists.RemoveAt(index + 1);
                }
            }

            if (addPressed) {
                UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "add Playlist");
                _creator.musicPlaylists.Add(new MasterAudio.Playlist());
            }
        }
        // Music playlist End

        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(ref isDirty, _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(ref isDirty, _creator, "change New Event Name");
                _creator.newEventName = newEvent;
            }

            GUI.contentColor = Color.green;

            EditorGUILayout.BeginHorizontal();

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

            EditorGUILayout.EndHorizontal();

            EditorGUI.indentLevel = 0;
            if (_creator.customEventsToCreate.Count == 0) {
                DTGUIHelper.ShowLargeBarAlert("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++) {
                EditorGUI.indentLevel = 0;
                var anEvent = _creator.customEventsToCreate[i];

                EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                var exp =  DTGUIHelper.Foldout(anEvent.eventExpanded, anEvent.EventName);
                if (exp != anEvent.eventExpanded) {
                    UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "toggle expand Custom Event");
                    anEvent.eventExpanded = exp;
                }

                GUILayout.FlexibleSpace();
                var newName = GUILayout.TextField(anEvent.ProspectiveName, GUILayout.Width(170));
                if (newName != anEvent.ProspectiveName) {
                    UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _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 (anEvent.eventExpanded) {
                    EditorGUI.indentLevel = 1;
                    var rcvMode = (MasterAudio.CustomEventReceiveMode) EditorGUILayout.EnumPopup("Send To Receivers", anEvent.eventReceiveMode);
                    if (rcvMode != anEvent.eventReceiveMode) {
                        UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Send To Receivers");
                        anEvent.eventReceiveMode = rcvMode;
                    }

                    if (rcvMode == MasterAudio.CustomEventReceiveMode.WhenDistanceLessThan || rcvMode == MasterAudio.CustomEventReceiveMode.WhenDistanceMoreThan) {
                        var newDist = EditorGUILayout.Slider("Distance Threshold", anEvent.distanceThreshold, 0f, float.MaxValue);
                        if (newDist != anEvent.distanceThreshold) {
                            UndoHelper.RecordObjectPropertyForUndo(ref isDirty, _creator, "change Distance Threshold");
                            anEvent.distanceThreshold = newDist;
                        }
                    }

                    EditorGUILayout.Separator();
                }
            }

            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);
        }

        //DrawDefaultInspector();
    }
    private void PlayPlaylistSong(MusicSetting setting)
    {
        AudioSource audioClip;
        AudioSource transClip;

        if (activeAudio == null)
        {
            Debug.LogError("PlaylistController prefab is not in your scene. Cannot play a song.");
            return;
        }

        if (activeAudio.clip != null)
        {
            var newClipName = string.Empty;
            if (setting.clip != null)
            {
                newClipName = setting.clip.name;
            }
            if (activeAudio.clip.name.Equals(newClipName))
            {
                // ignore, it's the same clip! Playing the same causes it to stop.
                return;
            }
        }
		
        if (activeAudio.clip == null)
        {
            audioClip = activeAudio;
            transClip = transitioningAudio;
        }
        else if (transitioningAudio.clip == null)
        {
            audioClip = transitioningAudio;
            transClip = activeAudio;
        }
        else
        {
            // both are busy!
            audioClip = transitioningAudio;
            transClip = activeAudio;
        }

        if (setting.clip != null)
        {
            audioClip.clip = setting.clip;
            audioClip.pitch = setting.pitch;
        }

        audioClip.loop = SongShouldLoop(setting);

        AudioClip clipToPlay = null;

        switch (setting.audLocation)
        {
            case MasterAudio.AudioLocation.Clip:
                if (setting.clip == null)
                {
                    MasterAudio.LogWarning("MasterAudio will not play empty Playlist clip for PlaylistController '" + this.transform.name + "'.");
                    return;
                }

                clipToPlay = setting.clip;
                break;
            case MasterAudio.AudioLocation.ResourceFile:
                clipToPlay = AudioResourceOptimizer.PopulateResourceSongToPlaylistController(setting.resourceFileName, this.currentPlaylist.playlistName);
				if (clipToPlay == null)
                {
                    return;
                }
                break;
        }

        audioClip.clip = clipToPlay;
        audioClip.pitch = setting.pitch;

        // set last known time for current song.
        if (currentSong != null)
        {
            currentSong.lastKnownTimePoint = activeAudio.timeSamples;
        }

        if (MasterAudio.Instance.CrossFadeTime == 0 || transClip.clip == null)
        {
            CeaseAudioSource(transClip);
            audioClip.volume = setting.volume * PlaylistVolume;
        }
        else
        {
            audioClip.volume = 0f;
            isCrossFading = true;
            duckingMode = AudioDuckingMode.NotDucking;
            crossFadeStartTime = Time.realtimeSinceStartup;
        }

        SetDuckProperties();

        audioClip.Play(); // need to play before setting time or it sometimes resets back to zero.

		if (syncGroupNum > 0) {
			var firstMatchingGroupController = PlaylistController.Instances.Find(delegate(PlaylistController obj) {
				return obj != this && obj.syncGroupNum == syncGroupNum && obj.ActiveAudioSource.isPlaying;
			});
			
			if (firstMatchingGroupController != null) {
                audioClip.timeSamples = firstMatchingGroupController.activeAudio.timeSamples;
			}
		}
		
        if (currentPlaylist != null)
        {
            switch (currentPlaylist.songTransitionType)
            {
                case MasterAudio.SongFadeInPosition.SynchronizeClips:
                   	transitioningAudio.timeSamples = activeAudio.timeSamples;
                    break;
                case MasterAudio.SongFadeInPosition.NewClipFromLastKnownPosition:
					var thisSongInPlaylist = currentPlaylist.MusicSettings.Find(delegate(MusicSetting obj)
                    {
                        return obj == setting;
                    });

                    if (thisSongInPlaylist != null)
                    {
                        transitioningAudio.timeSamples = thisSongInPlaylist.lastKnownTimePoint;
                    }
                    break;
            }
        }

        if (SongChanged != null)
        {
            var clipName = String.Empty;
            if (audioClip != null)
            {
                clipName = audioClip.clip.name;
            }
            SongChanged(clipName);
        }

        activeAudio = audioClip;
        transitioningAudio = transClip;

        activeAudioEndVolume = setting.volume * PlaylistVolume;
        var transStartVol = transitioningAudio.volume;
        if (currentSong != null)
        {
            transStartVol = currentSong.volume;
        }

        transitioningAudioStartVolume = transStartVol * PlaylistVolume;
        currentSong = setting;
    }
    private void AddSongToPlaylist(MasterAudio.Playlist pList, AudioClip aClip)
    {
        var lastClip = pList.MusicSettings[pList.MusicSettings.Count - 1];

        MusicSetting mus;

        UndoHelper.RecordObjectPropertyForUndo(sounds, "add Song");

        if (lastClip.clip == null) {
            mus = lastClip;
            mus.clip = aClip;
        } else {
            mus = new MusicSetting() {
                volume = 1f,
                pitch = 1f,
                isExpanded = true,
                audLocation = pList.bulkLocationMode
            };

            switch (pList.bulkLocationMode) {
                case MasterAudio.AudioLocation.Clip:
                    mus.clip = aClip;
                    mus.songName = aClip.name;
                    break;
                case MasterAudio.AudioLocation.ResourceFile:
                    var resourceFileName = DTGUIHelper.GetResourcePath(aClip);
                    if (string.IsNullOrEmpty(resourceFileName)) {
                        resourceFileName = aClip.name;
                    }

                    mus.resourceFileName = resourceFileName;
                    mus.songName = aClip.name;
                    break;
            }

            pList.MusicSettings.Add(mus);
        }
    }
Exemplo n.º 21
0
    private void PlaySong(MusicSetting setting)
    {
        AudioSource audioClip;
        AudioSource transClip;

        if (activeAudio == null)
        {
            Debug.LogError("PlaylistController prefab is not in your scene. Cannot play a song.");
            return;
        }

        if (activeAudio.clip != null)
        {
            var newClipName = string.Empty;
            if (setting.clip != null)
            {
                newClipName = setting.clip.name;
            }
            if (activeAudio.clip.name.Equals(newClipName))
            {
                // ignore, it's the same clip! Playing the same causes it to stop.
                return;
            }
        }

        if (activeAudio.clip == null)
        {
            audioClip = activeAudio;
            transClip = transitioningAudio;
        }
        else if (transitioningAudio.clip == null)
        {
            audioClip = transitioningAudio;
            transClip = activeAudio;
        }
        else
        {
            // both are busy!
            audioClip = transitioningAudio;
            transClip = activeAudio;
        }

        if (setting.clip != null)
        {
            audioClip.clip  = setting.clip;
            audioClip.pitch = setting.pitch;
        }

        audioClip.loop = SongShouldLoop(setting);

        AudioClip clipToPlay = null;

        switch (setting.audLocation)
        {
        case MasterAudio.AudioLocation.Clip:
            if (setting.clip == null)
            {
                MasterAudio.LogWarning("MasterAudio will not play empty Playlist clip for PlaylistController '" + this.transform.name + "'.");
                return;
            }

            clipToPlay = setting.clip;
            break;

        case MasterAudio.AudioLocation.ResourceFile:
            clipToPlay = AudioResourceOptimizer.PopulateResourceSongToPlaylistController(setting.resourceFileName, this.currentPlaylist.playlistName);
            if (clipToPlay == null)
            {
                return;
            }
            break;
        }

        audioClip.clip  = clipToPlay;
        audioClip.pitch = setting.pitch;

        // set last known time for current song.
        if (currentSong != null)
        {
            currentSong.lastKnownTimePoint = activeAudio.timeSamples;
        }

        if (CrossFadeTime == 0 || transClip.clip == null)
        {
            CeaseAudioSource(transClip);
            audioClip.volume = setting.volume * PlaylistVolume;

            if (!ActiveAudioSource.isPlaying && currentPlaylist != null && currentPlaylist.fadeInFirstSong)
            {
                CrossFadeNow(audioClip);
            }
        }
        else
        {
            CrossFadeNow(audioClip);
        }

        SetDuckProperties();

        audioClip.Play(); // need to play before setting time or it sometimes resets back to zero.
        songsPlayedFromPlaylist++;

        var songTimeChanged = false;

        if (syncGroupNum > 0)
        {
            var firstMatchingGroupController = PlaylistController.Instances.Find(delegate(PlaylistController obj)
            {
                return(obj != this && obj.syncGroupNum == syncGroupNum && obj.ActiveAudioSource.isPlaying);
            });

            if (firstMatchingGroupController != null)
            {
                audioClip.timeSamples = firstMatchingGroupController.activeAudio.timeSamples;
                songTimeChanged       = true;
            }
        }

        // this code will adjust the starting position of a song, but shouldn't do so when you first change Playlists.
        if (currentPlaylist != null)
        {
            if (songsPlayedFromPlaylist <= 1)
            {
                audioClip.timeSamples = 0;                 // reset pointer so a new Playlist always starts at the beginning.
            }
            else
            {
                switch (currentPlaylist.songTransitionType)
                {
                case MasterAudio.SongFadeInPosition.SynchronizeClips:
                    if (!songTimeChanged)           // otherwise the sync group code above will get defeated.
                    {
                        transitioningAudio.timeSamples = activeAudio.timeSamples;
                    }
                    break;

                case MasterAudio.SongFadeInPosition.NewClipFromLastKnownPosition:
                    var thisSongInPlaylist = currentPlaylist.MusicSettings.Find(delegate(MusicSetting obj)
                    {
                        return(obj == setting);
                    });

                    if (thisSongInPlaylist != null)
                    {
                        transitioningAudio.timeSamples = thisSongInPlaylist.lastKnownTimePoint;
                    }
                    break;
                }
            }
        }

        if (SongChanged != null)
        {
            var clipName = String.Empty;
            if (audioClip != null)
            {
                clipName = audioClip.clip.name;
            }
            SongChanged(clipName);
        }

        activeAudio        = audioClip;
        transitioningAudio = transClip;

        activeAudioEndVolume = setting.volume * PlaylistVolume;
        var transStartVol = transitioningAudio.volume;

        if (currentSong != null)
        {
            transStartVol = currentSong.volume;
        }

        transitioningAudioStartVolume = transStartVol * PlaylistVolume;
        currentSong = setting;
    }
    public override void OnInspectorGUI()
    {
        EditorGUIUtility.LookLikeControls();
        EditorGUI.indentLevel = 0;

        MasterAudio sounds = (MasterAudio)target;

        if (sounds.logoTexture != null) {
            GUIHelper.DrawTexture(sounds.logoTexture);
        }

        this.ScanGroups(sounds);

        if (!isValid) {
            return;
        }

        var groupNameList = GroupNameList;

        var maxChars = 9;
        var busList = new List<string>();
        busList.Add(MasterAudioGroup.NO_BUS);
        busList.Add(NEW_BUS_NAME);

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

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

        bool isDirty = false;

        var playlistCont = GUIHelper.GetSinglePlaylistController();
        var plControllerInScene = playlistCont != null;

        var volumeBefore = sounds.masterAudioVolume;
        sounds.masterAudioVolume = EditorGUILayout.Slider("Master Audio Volume", sounds.masterAudioVolume, 0f, 1f);

        if (volumeBefore != sounds.masterAudioVolume) {
            // fix it for realtime adjustments!
            MasterAudio.MasterVolumeLevel = sounds.masterAudioVolume;
        }

        sounds.allowRetriggerAfterPercentage = EditorGUILayout.IntSlider("Retrigger Percentage", sounds.allowRetriggerAfterPercentage, 0, 100);
        sounds.audioSourceMode = (MasterAudio.AudioSourceMode) EditorGUILayout.EnumPopup("Audio Source Mode", sounds.audioSourceMode);
        sounds.missingLogMode = (MasterAudio.MissingSoundLogSeverity) EditorGUILayout.EnumPopup("Missing Sound Log Mode", sounds.missingLogMode);
        sounds.persistBetweenScenes = EditorGUILayout.Toggle("Persist Across Scenes", sounds.persistBetweenScenes);
        if (sounds.persistBetweenScenes && plControllerInScene) {
            GUIHelper.ShowColorWarning("*Playlist Controller will also persist between scenes!");
        }
        sounds.LogSounds = EditorGUILayout.Toggle("Log Sounds", sounds.LogSounds);

        EditorGUI.indentLevel = 0;
           	EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);

        sounds.showMusicDucking = EditorGUILayout.Toggle("Show Music Ducking", sounds.showMusicDucking);
        EditorGUILayout.EndHorizontal();

        if (sounds.showMusicDucking) {
            sounds.EnableMusicDucking = EditorGUILayout.Toggle("Enable Ducking", sounds.EnableMusicDucking);

            EditorGUI.indentLevel = 2;
            var buttonPressed = GUIHelper.AddSingleFoldOutListItemButtons();

            switch (buttonPressed) {
                case GUIHelper.DTFunctionButtons.Add:
                    sounds.musicDuckingSounds.Add(MasterAudio.NO_GROUP_NAME);
                    isDirty = true;
                    break;
                case GUIHelper.DTFunctionButtons.Remove:
                    if (sounds.musicDuckingSounds.Count > 0) {
                        sounds.musicDuckingSounds.RemoveAt(sounds.musicDuckingSounds.Count - 1);
                    }
                    isDirty = true;
                    break;
            }

            if (sounds.musicDuckingSounds.Count == 0) {
             	GUIHelper.ShowColorWarning("No ducking sounds set up yet.");
            } else {
                for (var i = 0; i < sounds.musicDuckingSounds.Count; i++) {
                    var index = groupNameList.IndexOf(sounds.musicDuckingSounds[i]);
                    if (index == -1) {
                        index = 0;
                    }
                    var newIndex = EditorGUILayout.Popup(index, groupNameList.ToArray());
                    if (newIndex >= 0) {
                        sounds.musicDuckingSounds[i] = groupNameList[newIndex];
                    }
                }
            }
        }

        // Sound Groups Start
        EditorGUILayout.BeginHorizontal();
        EditorGUI.indentLevel = 0;  // Space will handle this for the header

        EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
        sounds.areGroupsExpanded = EditorGUILayout.Toggle("Show Group Mixer", sounds.areGroupsExpanded);

        EditorGUILayout.EndHorizontal();
        EditorGUILayout.EndHorizontal();

        GameObject groupToDelete = null;

        if (sounds.areGroupsExpanded) {
            EditorGUI.indentLevel = 0;

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

            GUI.color = Color.yellow;

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

            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;
                            }

                            CreateSoundGroup(sounds, aClip);
                        }
                    }
                    Event.current.Use();
                    break;
            }
            EditorGUILayout.EndVertical();
            // create groups end

            EditorGUILayout.LabelField("Group Control", EditorStyles.miniBoldLabel);

            if (sounds.groupBuses.Count > 0) {
                sounds.groupByBus = GUILayout.Toggle(sounds.groupByBus, "Group by Bus");
            }

            GUIHelper.DTFunctionButtons groupButtonPressed = GUIHelper.DTFunctionButtons.None;

            MasterAudioGroup aGroup = null;
            if (this.groups.Count == 0) {
                GUIHelper.ShowColorWarning("You currently have zero sound groups.");
            } else {
                int? busToCreate = null;

                if (this.groups.Count >= MasterAudio.MAX_SOUND_GROUPS - 1) {
                    GUIHelper.ShowColorWarning("*Free version allows a maximum of " + MasterAudio.MAX_SOUND_GROUPS + " Sound Groups.");
                }

                for (var l = 0; l < this.groups.Count; l++) {
                    EditorGUI.indentLevel = 0;
                    aGroup = this.groups[l];

                    string sType = string.Empty;
                    if (Application.isPlaying) {
                        sType = aGroup.name;
                    }

                    EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                    var groupName = aGroup.name;

                    EditorGUILayout.LabelField(groupName, EditorStyles.label, GUILayout.MinWidth(50));
                    //GUILayout.Space(90);

                    EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(50));

                    // 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; // remove later
                    }

                    aGroup.busIndex = busIndex;
                    GUI.color = Color.white;

                    if (selectedBusIndex != busIndex) {
                        if (aGroup.busIndex == 1) {
                            busToCreate = l;
                        } else if (Application.isPlaying && busIndex >= MasterAudio.HARD_CODED_BUS_OPTIONS) {
                            var statGroup = MasterAudio.GrabGroup(sType);
                            statGroup.busIndex = busIndex;
                        }
                    }

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

                    aGroup.groupMasterVolume = GUILayout.HorizontalSlider(aGroup.groupMasterVolume, 0f, 1f, GUILayout.Width(60));

                    GUI.contentColor = Color.white;
                    groupButtonPressed = GUIHelper.AddMixerButtons(aGroup, "Group", sounds);

                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndHorizontal();

                    switch (groupButtonPressed) {
                        case GUIHelper.DTFunctionButtons.Play:
                            MasterAudio.PlaySound(aGroup.name);
                            break;
                        case GUIHelper.DTFunctionButtons.Mute:
                            isDirty = true;

                            if (Application.isPlaying) {
                                if (aGroup.isMuted) {
                                    MasterAudio.UnmuteGroup(sType);
                                } else {
                                    MasterAudio.MuteGroup(sType);
                                }
                            } else {
                                aGroup.isMuted = !aGroup.isMuted;
                                if (aGroup.isMuted) {
                                    aGroup.isSoloed = false;
                                }
                            }
                            break;
                        case GUIHelper.DTFunctionButtons.Solo:
                            isDirty = true;
                            if (Application.isPlaying) {
                                if (aGroup.isSoloed) {
                                    MasterAudio.UnsoloGroup(sType);
                                } else {
                                    MasterAudio.SoloGroup(sType);
                                }
                            } else {
                                aGroup.isSoloed = !aGroup.isSoloed;
                                if (aGroup.isSoloed) {
                                    aGroup.isMuted = false;
                                }
                            }
                            break;
                        case GUIHelper.DTFunctionButtons.Go:
                            Selection.activeObject = aGroup.transform;
                            break;
                        case GUIHelper.DTFunctionButtons.Remove:
                            isDirty = true;
                            groupToDelete = aGroup.transform.gameObject;
                            break;
                    }

                    EditorUtility.SetDirty(aGroup);
                }

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

                if (groupToDelete != null) {
                    GameObject.DestroyImmediate(groupToDelete);
                }

                EditorGUILayout.Separator();
                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(10);
                GUI.contentColor = Color.green;
                if (GUILayout.Button(new GUIContent("Mute/Solo Reset", "Turn off all group mute and solo switches"), EditorStyles.toolbarButton, GUILayout.Width(120))) {
                    isDirty = true;
                    for (var l = 0; l < this.groups.Count; l++) {
                        aGroup = this.groups[l];
                        aGroup.isSoloed = false;
                        aGroup.isMuted = false;
                    }

                }

                GUILayout.Space(6);

                if (GUILayout.Button(new GUIContent("Max Group Volumes", "Reset all group volumes to full"), EditorStyles.toolbarButton, GUILayout.Width(120))) {
                    isDirty = true;
                    for (var l = 0; l < this.groups.Count; l++) {
                        aGroup = this.groups[l];
                        aGroup.groupMasterVolume = 1f;
                    }
                }

                GUI.contentColor = Color.white;

                EditorGUILayout.EndHorizontal();
            }
            // Sound Groups End

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

                GroupBus aBus = null;
                GUIHelper.DTFunctionButtons busButtonPressed = GUIHelper.DTFunctionButtons.None;
                int? busToDelete = null;
                int? busToSolo = null;
                int? busToMute = null;

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

                    EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);

                    aBus.busName = EditorGUILayout.TextField("", aBus.busName);

                    EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(50));

                    GUI.contentColor = Color.green;

                    GUILayout.TextField("V " + aBus.volume.ToString("N2"), 6, EditorStyles.miniLabel);
                    aBus.volume = GUILayout.HorizontalSlider(aBus.volume, 0f, 1f, GUILayout.Width(60));

                    GUI.contentColor = Color.white;

                    busButtonPressed = GUIHelper.AddMixerBusButtons(aBus, sounds);

                    switch (busButtonPressed) {
                        case GUIHelper.DTFunctionButtons.Remove:
                            busToDelete = i;
                            break;
                        case GUIHelper.DTFunctionButtons.Solo:
                            busToSolo = i;
                            break;
                        case GUIHelper.DTFunctionButtons.Mute:
                            busToMute = i;
                            break;
                    }

                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndHorizontal();
                }

                if (busToDelete.HasValue) {
                    DeleteBus(busToDelete.Value, sounds);
                }
                if (busToMute.HasValue) {
                    MuteBus(busToMute.Value, sounds);
                }
                if (busToSolo.HasValue) {
                    SoloBus(busToSolo.Value, sounds);
                }

                EditorGUILayout.Separator();
                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(10);
                GUI.contentColor = Color.green;

                if (GUILayout.Button(new GUIContent("Mute/Solo Reset", "Turn off all bus mute and solo switches"), EditorStyles.toolbarButton, GUILayout.Width(120))) {
                    isDirty = true;
                    for (var l = 0; l < sounds.groupBuses.Count; l++) {
                        aBus = sounds.groupBuses[l];
                        aBus.isSoloed = false;
                        aBus.isMuted = false;
                    }
                }

                GUILayout.Space(6);

                if (GUILayout.Button(new GUIContent("Max Bus Volumes", "Reset all bus volumes to full"), EditorStyles.toolbarButton, GUILayout.Width(120))) {
                    isDirty = true;
                    for (var l = 0; l < sounds.groupBuses.Count; l++) {
                        aBus = sounds.groupBuses[l];
                        aBus.volume = 1f;
                    }
                }

                GUI.contentColor = Color.white;

                EditorGUILayout.EndHorizontal();
            }
        }
        // Sound Buses End

        // Music playlist Start
        EditorGUILayout.BeginHorizontal();
        EditorGUI.indentLevel = 0;  // Space will handle this for the header

        if (sounds.audioSourceMode == MasterAudio.AudioSourceMode.PlaylistController) {
            EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
            sounds.playListExpanded = EditorGUILayout.Toggle("Show Playlist Settings", sounds.playListExpanded);

            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndHorizontal();

            if (sounds.playListExpanded) {
                GUIHelper.ShowColorWarning("*If you choose Start playlist on Awake, the top playlist will be used.");
                sounds.playlistControls._startPlaylistOnAwake = EditorGUILayout.Toggle("Start playlist on Awake", sounds.playlistControls._startPlaylistOnAwake );
                sounds.playlistControls._shuffle = EditorGUILayout.Toggle("Shuffle mode", sounds.playlistControls._shuffle);
                sounds.playlistControls._autoAdvance = EditorGUILayout.Toggle("Auto advance clips", sounds.playlistControls._autoAdvance);
                sounds.playlistControls._repeatPlaylist = EditorGUILayout.Toggle("Repeat Playlist", sounds.playlistControls._repeatPlaylist);
                sounds.playlistControls._loopClips = EditorGUILayout.Toggle("Loop clips", sounds.playlistControls._loopClips);

                if (sounds.playlistControls._autoAdvance && sounds.playlistControls._loopClips) {
                    GUIHelper.ShowColorWarning("*You cannot use looping and auto advance at the same time.");
                }

                EditorGUILayout.Separator();

                if (!plControllerInScene) {
                    GUIHelper.ShowColorWarning("There is no Playlist Controller in the scene. Music will not play.");
                    GUI.contentColor = Color.green;
                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Space(10);
                    if (GUILayout.Button(new GUIContent("Create Playlist Controller"), EditorStyles.toolbarButton, GUILayout.Width(150))) {
                        var go = GameObject.Instantiate(sounds.playlistControllerPrefab);
                        go.name = "PlaylistController";
                    }
                    EditorGUILayout.EndHorizontal();
                    GUI.contentColor = Color.white;
                    EditorGUILayout.Separator();
                }

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

                EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                sounds.playlistEditorExpanded = GUIHelper.Foldout(sounds.playlistEditorExpanded, "Playlists");

                EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(100));

                if (sounds.musicPlaylists.Count > 0) {
                    GUIContent content;
                    var collapseIcon = '\u2261'.ToString();
                    content = new GUIContent(collapseIcon, "Click to collapse all");
                    var masterCollapse = GUILayout.Button(content, EditorStyles.toolbarButton);

                    var expandIcon = '\u25A1'.ToString();
                    content = new GUIContent(expandIcon, "Click to expand all");
                    var masterExpand = GUILayout.Button(content, EditorStyles.toolbarButton);
                    if (masterExpand) {
                        ExpandCollapseAllPlaylists(sounds, true);
                    }
                    if (masterCollapse) {
                        ExpandCollapseAllPlaylists(sounds, false);
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndHorizontal();

                    if (sounds.playlistEditorExpanded) {
                        int? playlistToRemove = null;
                        int? playlistToInsertAt = null;
                        int? playlistToMoveUp = null;
                        int? playlistToMoveDown = null;

                        for (var i = 0; i < sounds.musicPlaylists.Count; i++) {
                            EditorGUILayout.Separator();
                            var aList = sounds.musicPlaylists[i];

                            EditorGUI.indentLevel = 1;
                            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                            aList.isExpanded = GUIHelper.Foldout(aList.isExpanded, "Playlist: " + aList.playlistName);

                            var playlistButtonPressed = GUIHelper.AddFoldOutListItemButtons(i, sounds.musicPlaylists.Count, "playlist", false, true);

                            EditorGUILayout.EndHorizontal();

                            if (!aList.isExpanded) {
                                continue;
                            }

                            EditorGUI.indentLevel = 5;
                            aList.playlistName = EditorGUILayout.TextField("Name", aList.playlistName);

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

                            GUI.color = Color.yellow;

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

                            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;
                                            }

                                            AddSongToPlaylist(aList, aClip);
                                        }
                                    }
                                    Event.current.Use();
                                    break;
                            }
                            EditorGUILayout.EndVertical();

                            EditorGUI.indentLevel = 2;

                            int? addIndex = null;
                            int? removeIndex = null;
                            int? moveUpIndex = null;
                            int? moveDownIndex = null;

                            for (var j = 0; j < aList.MusicSettings.Count; j++) {
                                var aSong = aList.MusicSettings[j];
                                var clipName = aSong.clip == null ? "Empty" : aSong.clip.name;
                                EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                                EditorGUI.indentLevel = 2;
                                aSong.isExpanded = GUIHelper.Foldout(aSong.isExpanded, clipName);
                                var songButtonPressed = GUIHelper.AddFoldOutListItemButtons(j, aList.MusicSettings.Count, "clip", false, true);
                                EditorGUILayout.EndHorizontal();

                                if (aSong.isExpanded) {
                                    EditorGUI.indentLevel = 6;
                                    aSong.clip = (AudioClip) EditorGUILayout.ObjectField("Clip", aSong.clip, typeof(AudioClip), true);
                                    aSong.volume = EditorGUILayout.Slider("Volume", aSong.volume, 0f, 1f);
                                    aSong.pitch = EditorGUILayout.Slider("Pitch", aSong.pitch, 0f, 10f);
                                }

                                switch (songButtonPressed) {
                                    case GUIHelper.DTFunctionButtons.Add:
                                        addIndex = j;
                                        break;
                                    case GUIHelper.DTFunctionButtons.Remove:
                                        removeIndex = j;
                                        break;
                                    case GUIHelper.DTFunctionButtons.ShiftUp:
                                        moveUpIndex = j;
                                        break;
                                    case GUIHelper.DTFunctionButtons.ShiftDown:
                                        moveDownIndex = j;
                                        break;
                                }
                            }

                            if (addIndex.HasValue) {
                                var mus = new MusicSetting();
                                aList.MusicSettings.Insert(addIndex.Value + 1, mus);
                            } else if (removeIndex.HasValue) {
                                if (aList.MusicSettings.Count <= 1) {
                                    GUIHelper.ShowAlert("You cannot delete the last clip. You do not have to use the clips though.");
                                } else {
                                    aList.MusicSettings.RemoveAt(removeIndex.Value);
                                }
                            } else if (moveUpIndex.HasValue) {
                                var item = aList.MusicSettings[moveUpIndex.Value];
                                aList.MusicSettings.Insert(moveUpIndex.Value - 1, item);
                                aList.MusicSettings.RemoveAt(moveUpIndex.Value + 1);
                            } else if (moveDownIndex.HasValue) {
                                var index = moveDownIndex.Value + 1;

                                var item = aList.MusicSettings[index];
                                aList.MusicSettings.Insert(index - 1, item);
                                aList.MusicSettings.RemoveAt(index + 1);
                            }

                            switch (playlistButtonPressed) {
                                case GUIHelper.DTFunctionButtons.Remove:
                                    playlistToRemove = i;
                                    break;
                                case GUIHelper.DTFunctionButtons.Add:
                                    playlistToInsertAt = i;
                                    break;
                                case GUIHelper.DTFunctionButtons.ShiftUp:
                                    playlistToMoveUp = i;
                                    break;
                                case GUIHelper.DTFunctionButtons.ShiftDown:
                                    playlistToMoveDown = i;
                                    break;
                            }
                        }

                        if (playlistToRemove.HasValue) {
                            if (sounds.musicPlaylists.Count <= 1) {
                                GUIHelper.ShowAlert("You cannot delete the last Playlist. You do not have to use it though.");
                            } else {
                                sounds.musicPlaylists.RemoveAt(playlistToRemove.Value);
                            }
                        }
                        if (playlistToInsertAt.HasValue) {
                            var pl = new MasterAudio.Playlist();
                            sounds.musicPlaylists.Insert(playlistToInsertAt.Value + 1, pl);
                        }
                        if (playlistToMoveUp.HasValue) {
                            var item = sounds.musicPlaylists[playlistToMoveUp.Value];
                            sounds.musicPlaylists.Insert(playlistToMoveUp.Value - 1, item);
                            sounds.musicPlaylists.RemoveAt(playlistToMoveUp.Value + 1);
                        }
                        if (playlistToMoveDown.HasValue) {
                            var index = playlistToMoveDown.Value + 1;

                            var item = sounds.musicPlaylists[index];
                            sounds.musicPlaylists.Insert(index - 1, item);
                            sounds.musicPlaylists.RemoveAt(index + 1);
                        }
                    }
                } else {
                 	GUILayout.FlexibleSpace();
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndHorizontal();
                }
            }
            // Music playlist End
        } else {
            EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
            GUIHelper.ShowColorWarning("Playlist Controller disabled by setting: 'Audio Source Mode'");

            EditorGUILayout.EndHorizontal();
        }

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

        //DrawDefaultInspector();
    }
    public override void OnInspectorGUI()
    {
        EditorGUIUtility.LookLikeControls();
        EditorGUI.indentLevel = 0;

        sounds = (MasterAudio)target;

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

        this.ScanGroups();

        if (!isValid) {
            return;
        }

        var isInProjectView = DTGUIHelper.IsPrefabInProjectView(sounds);

        playlistNames = new List<string>();
        MasterAudio.Playlist pList = null;

        var maxPlaylistNameChars = 11;
        for (var i = 0; i < sounds.musicPlaylists.Count; i++) {
            pList = sounds.musicPlaylists[i];

            playlistNames.Add(pList.playlistName);
            if (pList.playlistName.Length > maxPlaylistNameChars) {
                maxPlaylistNameChars = pList.playlistName.Length;
            }
        }

        var groupNameList = GroupNameList;

        var busFilterList = new List<string>();
        busFilterList.Add(MasterAudio.ALL_BUSES_NAME);
        busFilterList.Add(MasterAudioGroup.NO_BUS);

        var maxChars = 9;
        var busList = new List<string>();
        busList.Add(MasterAudioGroup.NO_BUS);
        busList.Add(NEW_BUS_NAME);

        var busVoiceLimitList = new List<string>();
        busVoiceLimitList.Add(MasterAudio.NO_VOICE_LIMIT_NAME);

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

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

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

        PlaylistController.Instances = null;
        var pcs = PlaylistController.Instances;
        var plControllerInScene = pcs.Count > 0;

        // mixer master volume!
        EditorGUILayout.BeginHorizontal();
        var volumeBefore = sounds.masterAudioVolume;
        GUILayout.Label("Master Mixer Volume");
        GUILayout.Space(23);

        var newMasterVol = EditorGUILayout.Slider(sounds.masterAudioVolume, 0f, 1f, GUILayout.Width(252));
        if (newMasterVol != sounds.masterAudioVolume) {
            UndoHelper.RecordObjectPropertyForUndo(sounds, "change Master Mixer Volume");
            if (Application.isPlaying) {
                MasterAudio.MasterVolumeLevel = newMasterVol;
            } else {
                sounds.masterAudioVolume = newMasterVol;
            }
        }
        GUILayout.Space(10);

        var mixerMuteButtonPressed = DTGUIHelper.AddMixerMuteButton("Mixer", sounds);

        GUILayout.FlexibleSpace();

        if (mixerMuteButtonPressed == DTGUIHelper.DTFunctionButtons.Mute) {
            UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Mixer Mute");

            sounds.mixerMuted = !sounds.mixerMuted;
            if (Application.isPlaying) {
                MasterAudio.MixerMuted = sounds.mixerMuted;
            } else {
                for (var i = 0; i < groups.Count; i++) {
                    var aGroup = groups[i];
                    aGroup.isMuted = sounds.mixerMuted;
                    if (aGroup.isMuted) {
                        aGroup.isSoloed = false;
                    }
                }
            }
        }

        EditorGUILayout.EndHorizontal();

        if (volumeBefore != sounds.masterAudioVolume) {
            // fix it for realtime adjustments!
            MasterAudio.MasterVolumeLevel = sounds.masterAudioVolume;
        }

        // playlist master volume!
        if (plControllerInScene) {
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Master Playlist Volume");
            GUILayout.Space(14);
            var newPlaylistVol = EditorGUILayout.Slider(sounds.masterPlaylistVolume, 0f, 1f, GUILayout.Width(252));
            if (newPlaylistVol != sounds.masterPlaylistVolume) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "change Master Playlist Volume");
                if (Application.isPlaying) {
                    MasterAudio.PlaylistMasterVolume = newPlaylistVol;
                } else {
                    sounds.masterPlaylistVolume = newPlaylistVol;
                }
            }
            GUILayout.Space(10);
            var playlistMuteButtonPressed = DTGUIHelper.AddPlaylistMuteButton("All Playlists", sounds);
            if (playlistMuteButtonPressed == DTGUIHelper.DTFunctionButtons.Mute) {
                if (Application.isPlaying) {
                    MasterAudio.PlaylistsMuted = !MasterAudio.PlaylistsMuted;
                } else {
                    sounds.playlistsMuted = !sounds.playlistsMuted;

                    for (var i = 0; i < pcs.Count; i++) {
                        if (sounds.playlistsMuted) {
                            pcs[i].MutePlaylist();
                        } else {
                            pcs[i].UnmutePlaylist();
                        }
                    }
                }
            }

            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Master Crossfade Time");
            GUILayout.Space(11);
            var newCrossTime = EditorGUILayout.Slider(sounds.crossFadeTime, 0f, 10f, GUILayout.Width(252));
            if (newCrossTime != sounds.crossFadeTime) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "change Master Crossfade Time");
                sounds.crossFadeTime = newCrossTime;
            }
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            // jukebox controls
            if (Application.isPlaying) {
                DisplayJukebox();
            }
        }

        // Music Ducking Start
        EditorGUI.indentLevel = 0;
        GUI.color = sounds.showAdvancedSettings ? activeClr : inactiveClr;
        EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);

        var newAdv = EditorGUILayout.Toggle("Show Advanced", sounds.showAdvancedSettings);
        if (newAdv != sounds.showAdvancedSettings) {
            UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Show Advanced");
            sounds.showAdvancedSettings = newAdv;
        }
        EditorGUILayout.EndHorizontal();
        GUI.color = Color.white;

        if (sounds.showAdvancedSettings) {
            if (!Application.isPlaying) {
                var newPersist = EditorGUILayout.Toggle("Persist Across Scenes", sounds.persistBetweenScenes);
                if (newPersist != sounds.persistBetweenScenes) {
                    UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Persist Across Scenes");
                    sounds.persistBetweenScenes = newPersist;
                }
            }

            if (sounds.persistBetweenScenes && plControllerInScene) {
                DTGUIHelper.ShowColorWarning("*Playlist Controller will also persist between scenes!");
            }

            var newAutoPrioritize = EditorGUILayout.Toggle("Apply Distance Priority", sounds.prioritizeOnDistance);
            if (newAutoPrioritize != sounds.prioritizeOnDistance) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Prioritize By Distance");
                sounds.prioritizeOnDistance = newAutoPrioritize;
            }

            if (sounds.prioritizeOnDistance) {
                EditorGUI.indentLevel = 1;

                var reevalIndex = sounds.rePrioritizeEverySecIndex;

                var evalTimes = new List<string>();
                for (var i = 0; i < reevaluatePriorityTimes.Count; i++) {
                    evalTimes.Add(reevaluatePriorityTimes[i].ToString() + " seconds");
                }

                var newRepri = EditorGUILayout.Popup("Reprioritize Time Gap", reevalIndex, evalTimes.ToArray());
                if (newRepri != reevalIndex) {
                    UndoHelper.RecordObjectPropertyForUndo(sounds, "change Re-evaluate time");
                    sounds.rePrioritizeEverySecIndex = newRepri;
                }

                var newContinual = EditorGUILayout.Toggle("Use Clip Age Priority", sounds.useClipAgePriority);
                if (newContinual != sounds.useClipAgePriority) {
                    UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Use Clip Age Priority");
                    sounds.useClipAgePriority = newContinual;
                }
            }

            EditorGUI.indentLevel = 0;
            var newFast = EditorGUILayout.Toggle("Fast GUI Refresh", sounds.enableFastResponse);
            if (newFast != sounds.enableFastResponse) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Fast GUI Refresh");
                sounds.enableFastResponse = newFast;
            }

            var newGiz = EditorGUILayout.Toggle("Show Variation Gizmos", sounds.showGizmos);
            if (newGiz != sounds.showGizmos) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Show Variation Gizmos");
                sounds.showGizmos = newGiz;
            }

            var newResourcePause = EditorGUILayout.Toggle("Keep Paused Resources", sounds.resourceClipsPauseDoNotUnload);
            if (newResourcePause != sounds.resourceClipsPauseDoNotUnload) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Keep Paused Resources");
                sounds.resourceClipsPauseDoNotUnload = newResourcePause;
            }

            var newLog = EditorGUILayout.Toggle("Disable Logging", sounds.disableLogging);
            if (newLog != sounds.disableLogging) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Disable Logging");
                sounds.disableLogging = newLog;
            }

            if (!sounds.disableLogging) {
                newLog = EditorGUILayout.Toggle("Log All Sounds", sounds.LogSounds);
                if (newLog != sounds.LogSounds) {
                    if (Application.isPlaying) {
                        MasterAudio.LogSoundsEnabled = sounds.LogSounds;
                    }
                    sounds.LogSounds = newLog;
                }
            } else {
                DTGUIHelper.ShowLargeBarAlert("Logging is disabled.");
            }
        }

        // Music Ducking Start
        EditorGUI.indentLevel = 0;
        GUI.color = sounds.showMusicDucking ? activeClr : inactiveClr;
        EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);

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

        if (sounds.showMusicDucking) {
            var newEnableDuck = EditorGUILayout.BeginToggleGroup("Enable Ducking", sounds.EnableMusicDucking);
            if (newEnableDuck != sounds.EnableMusicDucking) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Enable Ducking");
                sounds.EnableMusicDucking = newEnableDuck;
            }

            EditorGUILayout.Separator();

            var newMult = EditorGUILayout.Slider("Ducked Vol Multiplier", sounds.duckedVolumeMultiplier, 0f, 1f);
            if (newMult != sounds.duckedVolumeMultiplier) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "change Ducked Vol Multiplier");
                sounds.DuckedVolumeMultiplier = newMult;
            }

            var newDefault = EditorGUILayout.Slider("Default Begin Unduck", sounds.defaultRiseVolStart, 0f, 1f);
            if (newDefault != sounds.defaultRiseVolStart) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "change Default Begin Unduck");
                sounds.defaultRiseVolStart = newDefault;
            }

            GUI.contentColor = Color.green;
            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(10);

            if (GUILayout.Button(new GUIContent("Add Duck Group"), EditorStyles.toolbarButton, GUILayout.Width(100))) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "Add Duck Group");
                sounds.musicDuckingSounds.Add(new DuckGroupInfo() {
                    soundType = MasterAudio.NO_GROUP_NAME,
                    riseVolStart = sounds.defaultRiseVolStart
                });
            }

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

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

                for (var i = 0; i < sounds.musicDuckingSounds.Count; i++) {
                    var duckSound = sounds.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(sounds, "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(sounds, "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(sounds, "delete Duck Group");
                    sounds.musicDuckingSounds.RemoveAt(duckSoundToRemove.Value);
                }

            }
            EditorGUILayout.EndToggleGroup();

            EditorGUILayout.Separator();
        }
        // Music Ducking End

        // Sound Groups Start
        EditorGUILayout.BeginHorizontal();
        EditorGUI.indentLevel = 0;  // Space will handle this for the header

        GUI.color = sounds.areGroupsExpanded ? activeClr : inactiveClr;
        EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
        var newGroupEx = EditorGUILayout.Toggle("Show Group Mixer", sounds.areGroupsExpanded);
        if (newGroupEx != sounds.areGroupsExpanded) {
            UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Show Group Mixer");
            sounds.areGroupsExpanded = newGroupEx;
        }

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

        GameObject groupToDelete = null;

        if (sounds.areGroupsExpanded) {
            EditorGUI.indentLevel = 0;

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

            var newBulkMode = (MasterAudio.AudioLocation) EditorGUILayout.EnumPopup("Variation Create Mode",  sounds.bulkLocationMode);
            if (newBulkMode != sounds.bulkLocationMode) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "change Bulk Variation Mode");
                sounds.bulkLocationMode = newBulkMode;
            }

            if (sounds.bulkLocationMode == MasterAudio.AudioLocation.ResourceFile) {
                DTGUIHelper.ShowColorWarning("*Resource mode: make sure to drag from Resource folders only.");
            }

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

            GUI.color = Color.yellow;

            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 {
                var dragArea = GUILayoutUtility.GetRect(0f,35f,GUILayout.ExpandWidth(true));
                GUI.Box (dragArea, "Drag Audio clips here to create groups!");

                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();

                            Transform groupTrans = null;

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

                                if (sounds.curDragGroupMode == MasterAudio.DragGroupMode.OneGroupPerClip) {
                                    CreateSoundGroup(aClip);
                                } else {
                                    if (groupTrans == null) { // one group with variations
                                        groupTrans = CreateSoundGroup(aClip);
                                    } else {
                                        CreateVariation(groupTrans, aClip);
                                        // create the variations
                                    }
                                }
                            }
                        }
                        Event.current.Use();
                        break;
                }
            }
            EditorGUILayout.EndVertical();
            // create groups end

            EditorGUILayout.LabelField("Group Control", EditorStyles.miniBoldLabel);

            if (sounds.groupBuses.Count > 0) {
                var newGroupByBus = GUILayout.Toggle(sounds.groupByBus, "Group by Bus");
                if (newGroupByBus != sounds.groupByBus) {
                    UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Group by Bus");
                    sounds.groupByBus = newGroupByBus;
                }
            }

            var newBusFilterIndex = -1;
            var busFilterActive = false;

            if (sounds.groupBuses.Count > 0) {
                busFilterActive = true;
                var oldBusFilter = busFilterList.IndexOf(sounds.busFilter);
                if (oldBusFilter == -1) {
                     oldBusFilter = 0;
                }

                newBusFilterIndex = EditorGUILayout.Popup("Bus Filter", oldBusFilter, busFilterList.ToArray());

                var newBusFilter = busFilterList[newBusFilterIndex];

                if (sounds.busFilter != newBusFilter) {
                    UndoHelper.RecordObjectPropertyForUndo(sounds, "change Bus Filter");
                    sounds.busFilter = newBusFilter;
                }
            }

            var newUseTextGroupFilter = EditorGUILayout.Toggle("Use Text Group Filter", sounds.useTextGroupFilter);
            if (newUseTextGroupFilter != sounds.useTextGroupFilter) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Use Text Group Filter");
                sounds.useTextGroupFilter = newUseTextGroupFilter;
            }

            if (sounds.useTextGroupFilter) {
                EditorGUI.indentLevel = 1;

                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(10);
                GUILayout.Label("Text Group Filter", GUILayout.Width(140));
                var newTextFilter = GUILayout.TextField(sounds.textGroupFilter, GUILayout.Width(180));
                if (newTextFilter != sounds.textGroupFilter) {
                    UndoHelper.RecordObjectPropertyForUndo(sounds, "change Text Group Filter");
                    sounds.textGroupFilter = newTextFilter;
                }
                GUILayout.Space(10);
                GUI.contentColor = Color.green;
                if (GUILayout.Button("Clear", EditorStyles.toolbarButton, GUILayout.Width(70))) {
                    sounds.textGroupFilter = string.Empty;
                }
                GUI.contentColor = Color.white;
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.Separator();
            }

            EditorGUI.indentLevel = 0;
            DTGUIHelper.DTFunctionButtons groupButtonPressed = DTGUIHelper.DTFunctionButtons.None;

            MasterAudioGroup aGroup = null;
            var filteredGroups = new List<MasterAudioGroup>();

            filteredGroups.AddRange(this.groups);

            if (busFilterActive && !string.IsNullOrEmpty(sounds.busFilter)) {
                if (newBusFilterIndex == 0) {
                    // no filter
                } else if (newBusFilterIndex == 1) {
                    filteredGroups.RemoveAll(delegate(MasterAudioGroup obj) {
                        return obj.busIndex != 0;
                    });
                } else {
                    filteredGroups.RemoveAll(delegate(MasterAudioGroup obj) {
                        return obj.busIndex != newBusFilterIndex;
                    });
                }
            }

            if (sounds.useTextGroupFilter) {
                if (!string.IsNullOrEmpty(sounds.textGroupFilter)) {
                    filteredGroups.RemoveAll(delegate(MasterAudioGroup obj) {
                        return !obj.transform.name.ToLower().Contains(sounds.textGroupFilter.ToLower());
                    });
                }
            }

            var totalVoiceCount = 0;

            if (groups.Count == 0) {
                DTGUIHelper.ShowColorWarning("*You currently have zero Sound Groups.");
            } else {
                var groupsFiltered = this.groups.Count - filteredGroups.Count;
                if (groupsFiltered > 0) {
                    DTGUIHelper.ShowLargeBarAlert(string.Format("{0} Group(s) filtered out.", groupsFiltered));
                }

                int? busToCreate = null;

                for (var l = 0; l < filteredGroups.Count; l++) {
                    EditorGUI.indentLevel = 0;
                    aGroup = filteredGroups[l];

                    string sType = string.Empty;
                    if (Application.isPlaying) {
                        sType = aGroup.name;
                    }

                    EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                    var groupName = aGroup.name;

                    if (Application.isPlaying) {
                        var groupVoices = aGroup.ActiveVoices;

                        GUI.color = Color.yellow;
                        if (aGroup.limitPolyphony && aGroup.voiceLimitCount == groupVoices) {
                            GUI.contentColor = Color.red;
                        }
                        GUILayout.Label(string.Format("[{0}]", groupVoices));
                        GUI.color = Color.white;
                        GUI.contentColor = Color.white;

                        totalVoiceCount += groupVoices;
                    }

                    EditorGUILayout.LabelField(groupName, EditorStyles.label, GUILayout.MinWidth(50));
                    //GUILayout.Space(90);

                    GUILayout.FlexibleSpace();
                    EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(50));

                    // 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) {
                            busToCreate = l;
                        } else if (busIndex >= MasterAudio.HARD_CODED_BUS_OPTIONS) {
                            GroupBus newBus = sounds.groupBuses[busIndex - MasterAudio.HARD_CODED_BUS_OPTIONS];
                            if (Application.isPlaying) {
                                var statGroup = MasterAudio.GrabGroup(sType);
                                statGroup.busIndex = busIndex;

                                if (newBus.isMuted) {
                                    MasterAudio.MuteGroup(aGroup.name);
                                } else if (newBus.isSoloed) {
                                    MasterAudio.SoloGroup(aGroup.name);
                                }
                            } else {
                                // check if bus soloed or muted.
                                if (newBus.isMuted) {
                                    aGroup.isMuted = true;
                                    aGroup.isSoloed = false;
                                } else if (newBus.isSoloed) {
                                    aGroup.isMuted = false;
                                    aGroup.isSoloed = true;
                                }
                            }
                        }
                    }

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

                    var newVol = GUILayout.HorizontalSlider(aGroup.groupMasterVolume, 0f, 1f, GUILayout.Width(60));
                    if (newVol != aGroup.groupMasterVolume) {
                        UndoHelper.RecordObjectPropertyForUndo(aGroup, "change Group Volume");
                        aGroup.groupMasterVolume = newVol;
                        if (Application.isPlaying) {
                            MasterAudio.SetGroupVolume(aGroup.name, aGroup.groupMasterVolume);
                        }
                    }

                    GUI.contentColor = Color.white;
                    DTGUIHelper.AddLedSignalLight(sounds, groupName);

                    groupButtonPressed = DTGUIHelper.AddMixerButtons(aGroup, "Group");

                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndHorizontal();

                    GroupBus groupBus = null;
                    var groupBusIndex = aGroup.busIndex - MasterAudio.HARD_CODED_BUS_OPTIONS;
                    if (groupBusIndex >= 0 && groupBusIndex < sounds.groupBuses.Count) {
                        groupBus = sounds.groupBuses[groupBusIndex];
                    }

                    switch (groupButtonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Play:
                            if (Application.isPlaying) {
                                MasterAudio.PlaySound(aGroup.name);
                            } else {
                                var rndIndex = UnityEngine.Random.Range(0, aGroup.groupVariations.Count);
                                var rndVar = aGroup.groupVariations[rndIndex];

                                if (rndVar.audLocation == MasterAudio.AudioLocation.ResourceFile) {
                                    MasterAudio.PreviewerInstance.Stop();
                                    MasterAudio.PreviewerInstance.PlayOneShot(Resources.Load(rndVar.resourceFileName) as AudioClip, rndVar.audio.volume);
                                } else {
                                    rndVar.audio.Play();
                                }
                            }
                            break;
                        case DTGUIHelper.DTFunctionButtons.Stop:
                            if (Application.isPlaying) {
                                MasterAudio.StopAllOfSound(aGroup.name);
                            } else {
                                var hasResourceFile = false;
                                for (var i = 0; i < aGroup.groupVariations.Count; i++) {
                                    aGroup.groupVariations[i].audio.Stop();
                                    if (aGroup.groupVariations[i].audLocation == MasterAudio.AudioLocation.ResourceFile) {
                                        hasResourceFile = true;
                                    }
                                }

                                if (hasResourceFile) {
                                    MasterAudio.PreviewerInstance.Stop();
                                }
                            }
                            break;
                        case DTGUIHelper.DTFunctionButtons.Mute:
                            if (groupBus != null && (groupBus.isMuted || groupBus.isSoloed)) {
                                if (Application.isPlaying) {
                                    Debug.LogWarning(NO_MUTE_SOLO_ALLOWED);
                                } else {
                                    DTGUIHelper.ShowAlert(NO_MUTE_SOLO_ALLOWED);
                                }
                            } else {
                                UndoHelper.RecordObjectPropertyForUndo(aGroup, "toggle Group mute");

                                if (Application.isPlaying) {
                                    if (aGroup.isMuted) {
                                        MasterAudio.UnmuteGroup(sType);
                                    } else {
                                        MasterAudio.MuteGroup(sType);
                                    }
                                } else {
                                    aGroup.isMuted = !aGroup.isMuted;
                                    if (aGroup.isMuted) {
                                        aGroup.isSoloed = false;
                                    }
                                }
                            }
                            break;
                        case DTGUIHelper.DTFunctionButtons.Solo:
                            if (groupBus != null && (groupBus.isMuted || groupBus.isSoloed)) {
                                if (Application.isPlaying) {
                                    Debug.LogWarning(NO_MUTE_SOLO_ALLOWED);
                                } else {
                                    DTGUIHelper.ShowAlert(NO_MUTE_SOLO_ALLOWED);
                                }
                            } else {
                                UndoHelper.RecordObjectPropertyForUndo(aGroup, "toggle Group solo");

                                if (Application.isPlaying) {
                                    if (aGroup.isSoloed) {
                                        MasterAudio.UnsoloGroup(sType);
                                    } else {
                                        MasterAudio.SoloGroup(sType);
                                    }
                                } else {
                                    aGroup.isSoloed = !aGroup.isSoloed;
                                    if (aGroup.isSoloed) {
                                        aGroup.isMuted = false;
                                    }
                                }
                            }
                            break;
                        case DTGUIHelper.DTFunctionButtons.Go:
                            Selection.activeObject = aGroup.transform;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            groupToDelete = aGroup.transform.gameObject;
                            break;
                    }

                    EditorUtility.SetDirty(aGroup);
                }

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

                if (groupToDelete != null) {
                    sounds.musicDuckingSounds.RemoveAll(delegate(DuckGroupInfo obj) {
                        return obj.soundType == groupToDelete.name;
                    });
                    UndoHelper.DestroyForUndo(groupToDelete);
                }

                if (Application.isPlaying) {
                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Space(6);
                    GUI.color = Color.yellow;
                    EditorGUILayout.LabelField(string.Format("[{0}] Total Active Voices", totalVoiceCount));
                    GUI.color = Color.white;
                    EditorGUILayout.EndHorizontal();
                }

                EditorGUILayout.Separator();
                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(10);
                GUI.contentColor = Color.green;
                if (GUILayout.Button(new GUIContent("Mute/Solo Reset", "Turn off all group mute and solo switches"), EditorStyles.toolbarButton, GUILayout.Width(120))) {
                    UndoHelper.RecordObjectsForUndo(this.groups.ToArray(), "Mute/Solo Reset");

                    for (var l = 0; l < this.groups.Count; l++) {
                        aGroup = this.groups[l];
                        aGroup.isSoloed = false;
                        aGroup.isMuted = false;
                    }

                }

                GUILayout.Space(6);

                if (GUILayout.Button(new GUIContent("Max Group Volumes", "Reset all group volumes to full"), EditorStyles.toolbarButton, GUILayout.Width(120))) {
                    UndoHelper.RecordObjectsForUndo(this.groups.ToArray(), "Max Group Volumes");

                    for (var l = 0; l < this.groups.Count; l++) {
                        aGroup = this.groups[l];
                        aGroup.groupMasterVolume = 1f;
                    }
                }

                GUI.contentColor = Color.white;

                EditorGUILayout.EndHorizontal();
            }
            // Sound Groups End

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

                GroupBus aBus = null;
                DTGUIHelper.DTFunctionButtons busButtonPressed = DTGUIHelper.DTFunctionButtons.None;
                int? busToDelete = null;
                int? busToSolo = null;
                int? busToMute = null;

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

                    EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);

                    if (Application.isPlaying) {
                        GUI.color = Color.yellow;
                        if (aBus.BusVoiceLimitReached) {
                            GUI.contentColor = Color.red;
                        }
                        GUILayout.Label(string.Format("[{0:D2}]", aBus.ActiveVoices));
                        GUI.color = Color.white;
                        GUI.contentColor = Color.white;
                    }

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

                    GUILayout.FlexibleSpace();

                    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(sounds, "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);

                    var newBusVol = GUILayout.HorizontalSlider(aBus.volume, 0f, 1f, GUILayout.Width(86));
                    if (newBusVol != aBus.volume) {
                        UndoHelper.RecordObjectPropertyForUndo(sounds, "change Bus Volume");
                        aBus.volume = newBusVol;
                        if (Application.isPlaying) {
                            MasterAudio.SetBusVolumeByName(aBus.busName, aBus.volume);
                        }
                    }

                    GUI.contentColor = Color.white;

                    busButtonPressed = DTGUIHelper.AddMixerBusButtons(aBus);

                    switch (busButtonPressed) {
                    case DTGUIHelper.DTFunctionButtons.Remove:
                        busToDelete = i;
                        break;
                    case DTGUIHelper.DTFunctionButtons.Solo:
                        busToSolo = i;
                        break;
                    case DTGUIHelper.DTFunctionButtons.Mute:
                        busToMute = i;
                        break;
                    }

                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndHorizontal();
                }

                if (busToDelete.HasValue) {
                    DeleteBus(busToDelete.Value);
                }
                if (busToMute.HasValue) {
                    MuteBus(busToMute.Value);
                }
                if (busToSolo.HasValue) {
                    SoloBus(busToSolo.Value);
                }

                if (Application.isPlaying) {
                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Space(6);
                    GUI.color = Color.yellow;
                    EditorGUILayout.LabelField(string.Format("[{0:D2}] Total Active Voices", totalVoiceCount));
                    GUI.color = Color.white;
                    EditorGUILayout.EndHorizontal();
                }

                EditorGUILayout.Separator();
                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(10);
                GUI.contentColor = Color.green;

                if (GUILayout.Button(new GUIContent("Mute/Solo Reset", "Turn off all bus mute and solo switches"), EditorStyles.toolbarButton, GUILayout.Width(120))) {
                    BusMuteSoloReset();
                }

                GUILayout.Space(6);

                if (GUILayout.Button(new GUIContent("Max Bus Volumes", "Reset all bus volumes to full"), EditorStyles.toolbarButton, GUILayout.Width(120))) {
                    UndoHelper.RecordObjectPropertyForUndo(sounds, "Max Bus Volumes");

                    for (var l = 0; l < sounds.groupBuses.Count; l++) {
                        aBus = sounds.groupBuses[l];
                        aBus.volume = 1f;
                    }
                }

                GUI.contentColor = Color.white;

                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.Separator();
        }
        // Sound Buses End

        // Music playlist Start
        EditorGUILayout.BeginHorizontal();
        EditorGUI.indentLevel = 0;  // Space will handle this for the header

        GUI.color = sounds.playListExpanded ? activeClr : inactiveClr;
        EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
        var isExp = EditorGUILayout.Toggle("Show Playlist Settings", sounds.playListExpanded);
        if (isExp != sounds.playListExpanded) {
            UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Show Playlist Settings");
            sounds.playListExpanded = isExp;
        }

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

        EditorGUILayout.EndHorizontal();

        if (sounds.playListExpanded) {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Playlist Controller Setup", EditorStyles.miniBoldLabel, GUILayout.Width(146));
            if (plControllerInScene) {
                GUILayout.FlexibleSpace();
                EditorGUILayout.LabelField("Sync Grp.", EditorStyles.miniBoldLabel, GUILayout.Width(54));
                EditorGUILayout.LabelField("Initial Playlist", EditorStyles.miniBoldLabel, GUILayout.Width(100));
                GUILayout.Space(204);
            }
            EditorGUILayout.EndHorizontal();

            if (!plControllerInScene) {
                DTGUIHelper.ShowColorWarning("There are no Playlist Controllers in the scene. Music will not play.");
            } else {
                int? indexToDelete = null;

                playlistNames.Insert(0, MasterAudio.NO_PLAYLIST_NAME);

                var syncGroupList = new List<string>();
                for (var i = 0; i < 4; i++) {
                    syncGroupList.Add((i + 1).ToString());
                }
                syncGroupList.Insert(0, MasterAudio.NO_GROUP_NAME);

                for (var i = 0; i < pcs.Count; i++) {
                    var control = pcs[i];
                    EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                    GUILayout.Label(control.name);

                    GUILayout.FlexibleSpace();

                    GUI.color = Color.cyan;
                    var syncIndex = syncGroupList.IndexOf(control.syncGroupNum.ToString());
                    if (syncIndex == -1) {
                        syncIndex = 0;
                    }
                    var newSync = EditorGUILayout.Popup("", syncIndex, syncGroupList.ToArray(), GUILayout.Width(55));
                    if (newSync != syncIndex) {
                        UndoHelper.RecordObjectPropertyForUndo(control, "change Controller Sync Group");
                        control.syncGroupNum = newSync;
                    }

                    var origIndex = playlistNames.IndexOf(control.startPlaylistName);
                    if (origIndex == -1) {
                        origIndex = 0;
                    }
                    var newIndex = EditorGUILayout.Popup("", origIndex, playlistNames.ToArray(), GUILayout.Width(playlistListWidth));
                    if (newIndex != origIndex) {
                        UndoHelper.RecordObjectPropertyForUndo(control, "change Playlist Controller initial Playlist");
                        control.startPlaylistName = playlistNames[newIndex];
                    }
                    GUI.color = Color.white;

                    GUI.contentColor = Color.green;
                    GUILayout.TextField("V " + control.playlistVolume.ToString("N2"), 6, EditorStyles.miniLabel);
                    var newVol = GUILayout.HorizontalSlider(control.playlistVolume, 0f, 1f, GUILayout.Width(74));

                    if (newVol != control.playlistVolume) {
                        UndoHelper.RecordObjectPropertyForUndo(control, "change Playlist Controller volume");
                        control.playlistVolume = newVol;
                        control.UpdateMasterVolume();
                    }

                    GUI.contentColor = Color.white;

                    var buttonPressed = DTGUIHelper.AddPlaylistControllerSetupButtons(control, "Playlist Controller", false);

                    EditorGUILayout.EndHorizontal();

                    switch (buttonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Go:
                            Selection.activeObject = control.transform;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            indexToDelete = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Mute:
                            control.ToggleMutePlaylist();
                            break;
                    }

                    EditorUtility.SetDirty(control);
                }

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

            EditorGUILayout.Separator();
            GUI.contentColor = Color.green;
            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(10);
            if (GUILayout.Button(new GUIContent("Create Playlist Controller"), EditorStyles.toolbarButton, GUILayout.Width(150))) {
                var go = GameObject.Instantiate(sounds.playlistControllerPrefab.gameObject);
                go.name = "PlaylistController";

                UndoHelper.CreateObjectForUndo(go as GameObject, "create Playlist Controller");
            }
            EditorGUILayout.EndHorizontal();
            GUI.contentColor = Color.white;
            EditorGUILayout.Separator();

            EditorGUILayout.LabelField("Playlist Setup", EditorStyles.miniBoldLabel);
            EditorGUI.indentLevel = 0;  // Space will handle this for the header

            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
            var oldPlayExpanded = DTGUIHelper.Foldout(sounds.playlistEditorExpanded, "Playlists");
            if (oldPlayExpanded != sounds.playlistEditorExpanded) {
                UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Playlists");
                sounds.playlistEditorExpanded = oldPlayExpanded;
            }

            EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(100));

            if (sounds.musicPlaylists.Count > 0) {
                GUIContent content;
                var collapseIcon = '\u2261'.ToString();
                content = new GUIContent(collapseIcon, "Click to collapse all");
                var masterCollapse = GUILayout.Button(content, EditorStyles.toolbarButton);

                var expandIcon = '\u25A1'.ToString();
                content = new GUIContent(expandIcon, "Click to expand all");
                var masterExpand = GUILayout.Button(content, EditorStyles.toolbarButton);
                if (masterExpand) {
                    ExpandCollapseAllPlaylists(true);
                }
                if (masterCollapse) {
                    ExpandCollapseAllPlaylists(false);
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndHorizontal();

                if (sounds.playlistEditorExpanded) {
                    int? playlistToRemove = null;
                    int? playlistToInsertAt = null;
                    int? playlistToMoveUp = null;
                    int? playlistToMoveDown = null;

                    for (var i = 0; i < sounds.musicPlaylists.Count; i++) {
                        EditorGUILayout.Separator();
                        var aList = sounds.musicPlaylists[i];

                        EditorGUI.indentLevel = 1;
                        EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
                        aList.isExpanded = DTGUIHelper.Foldout(aList.isExpanded, "Playlist: " + aList.playlistName);

                        var playlistButtonPressed = DTGUIHelper.AddFoldOutListItemButtons(i, sounds.musicPlaylists.Count, "playlist", false, true);

                        EditorGUILayout.EndHorizontal();

                        if (aList.isExpanded) {
                            EditorGUI.indentLevel = 0;
                            var newPlaylist = EditorGUILayout.TextField("Name", aList.playlistName);
                            if (newPlaylist != aList.playlistName) {
                                UndoHelper.RecordObjectPropertyForUndo(sounds, "change Name");
                                aList.playlistName = newPlaylist;
                            }

                            var crossfadeMode = (MasterAudio.Playlist.CrossfadeTimeMode) EditorGUILayout.EnumPopup("Crossfade Mode", aList.crossfadeMode);
                            if (crossfadeMode != aList.crossfadeMode) {
                                UndoHelper.RecordObjectPropertyForUndo(sounds, "change Crossfade Mode");
                                aList.crossfadeMode = crossfadeMode;
                            }
                            if (aList.crossfadeMode == MasterAudio.Playlist.CrossfadeTimeMode.Override) {
                                var newCF = EditorGUILayout.Slider("Crossfade time (sec)", aList.crossFadeTime, 0f, 10f);
                                if (newCF != aList.crossFadeTime) {
                                    UndoHelper.RecordObjectPropertyForUndo(sounds, "change Crossfade time (sec)");
                                    aList.crossFadeTime = newCF;
                                }
                            }

                            var newFadeIn = EditorGUILayout.Toggle("Fade In First Song", aList.fadeInFirstSong);
                            if (newFadeIn != aList.fadeInFirstSong) {
                                UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Fade In First Song");
                                aList.fadeInFirstSong = newFadeIn;
                            }

                            var newFadeOut = EditorGUILayout.Toggle("Fade Out Last Song", aList.fadeOutLastSong);
                            if (newFadeOut != aList.fadeOutLastSong) {
                                UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Fade Out Last Song");
                                aList.fadeOutLastSong = newFadeOut;
                            }

                            var newTransType = (MasterAudio.SongFadeInPosition) EditorGUILayout.EnumPopup("Song Transition Type", aList.songTransitionType);
                            if (newTransType != aList.songTransitionType) {
                                UndoHelper.RecordObjectPropertyForUndo(sounds, "change Song Transition Type");
                                aList.songTransitionType = newTransType;
                            }
                            if (aList.songTransitionType == MasterAudio.SongFadeInPosition.SynchronizeClips) {
                                DTGUIHelper.ShowColorWarning("*All clips must be of exactly the same length.");
                            }

                            EditorGUI.indentLevel = 0;
                            var newBulkMode = (MasterAudio.AudioLocation) EditorGUILayout.EnumPopup("Clip Create Mode",  aList.bulkLocationMode);
                            if (newBulkMode != aList.bulkLocationMode) {
                                UndoHelper.RecordObjectPropertyForUndo(sounds, "change Bulk Clip Mode");
                                aList.bulkLocationMode = newBulkMode;
                            }

                            EditorGUILayout.BeginHorizontal();
                            GUILayout.Space(10);
                            GUI.contentColor = Color.green;
                            if (GUILayout.Button(new GUIContent("Equalize Song Volumes"), EditorStyles.toolbarButton)) {
                                EqualizePlaylistVolumes(aList.MusicSettings);
                            }
                            GUILayout.FlexibleSpace();
                            EditorGUILayout.EndHorizontal();
                            GUI.contentColor = Color.white;
                            EditorGUILayout.Separator();

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

                            GUI.color = Color.yellow;

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

                            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;
                                            }

                                            AddSongToPlaylist(aList, aClip);
                                        }
                                    }
                                    Event.current.Use();
                                    break;
                            }
                            EditorGUILayout.EndVertical();

                            EditorGUI.indentLevel = 2;

                            int? addIndex = null;
                            int? removeIndex = null;
                            int? moveUpIndex = null;
                            int? moveDownIndex = null;

                            for (var j = 0; j < aList.MusicSettings.Count; j++) {
                                var aSong = aList.MusicSettings[j];
                                var clipName = "Empty";
                                switch (aSong.audLocation) {
                                    case MasterAudio.AudioLocation.Clip:
                                        if (aSong.clip != null) {
                                            clipName = aSong.clip.name;
                                        }
                                        break;
                                    case MasterAudio.AudioLocation.ResourceFile:
                                        if (!string.IsNullOrEmpty(aSong.resourceFileName)) {
                                            clipName = aSong.resourceFileName;
                                        }
                                        break;
                                }
                                EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                                EditorGUI.indentLevel = 2;

                                if (!string.IsNullOrEmpty(clipName) && string.IsNullOrEmpty(aSong.songName)) {
                                    switch (aSong.audLocation) {
                                        case MasterAudio.AudioLocation.Clip:
                                            aSong.songName = clipName;
                                            break;
                                        case MasterAudio.AudioLocation.ResourceFile:
                                            aSong.songName = clipName;
                                            break;
                                    }
                                }

                                var newSongExpanded = DTGUIHelper.Foldout(aSong.isExpanded, aSong.songName);
                                if (newSongExpanded != aSong.isExpanded) {
                                    UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Song expand");
                                    aSong.isExpanded = newSongExpanded;
                                }
                                var songButtonPressed = DTGUIHelper.AddFoldOutListItemButtons(j, aList.MusicSettings.Count, "clip", false, true, true);
                                EditorGUILayout.EndHorizontal();

                                if (aSong.isExpanded) {
                                    EditorGUI.indentLevel = 0;

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

                                    switch (aSong.audLocation) {
                                        case MasterAudio.AudioLocation.Clip:
                                            var newClip = (AudioClip) EditorGUILayout.ObjectField("Audio Clip", aSong.clip, typeof(AudioClip), true);
                                            if (newClip != aSong.clip) {
                                                UndoHelper.RecordObjectPropertyForUndo(sounds, "change Clip");
                                                aSong.clip = newClip;
                                                aSong.songName = newClip.name;
                                            }
                                            break;
                                        case MasterAudio.AudioLocation.ResourceFile:
                                            if (oldLocation != aSong.audLocation) {
                                                if (aSong.clip != null) {
                                                    Debug.Log("Audio clip removed to prevent unnecessary memory usage on Resource file Playlist clip.");
                                                }
                                                aSong.clip = null;
                                                aSong.songName = string.Empty;
                                            }

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

                                            GUI.color = Color.yellow;
                                            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(sounds, "change Resource Filename");

                                                            var resourceFileName = DTGUIHelper.GetResourcePath(aClip);
                                                            if (string.IsNullOrEmpty(resourceFileName)) {
                                                                resourceFileName = aClip.name;
                                                            }

                                                            aSong.resourceFileName = resourceFileName;
                                                            aSong.songName = aClip.name;
                                                        }
                                                    }
                                                    Event.current.Use();
                                                    break;
                                            }
                                            EditorGUILayout.EndVertical();

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

                                            break;
                                    }

                                    var newVol = EditorGUILayout.Slider("Volume", aSong.volume, 0f, 1f);
                                    if (newVol != aSong.volume) {
                                        UndoHelper.RecordObjectPropertyForUndo(sounds, "change Volume");
                                        aSong.volume = newVol;
                                    }

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

                                    var newLoop = EditorGUILayout.Toggle("Loop Clip", aSong.isLoop);
                                    if (newLoop != aSong.isLoop) {
                                        UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Loop Clip");
                                        aSong.isLoop = newLoop;
                                    }
                                }

                                switch (songButtonPressed) {
                                    case DTGUIHelper.DTFunctionButtons.Add:
                                        addIndex = j;
                                        break;
                                    case DTGUIHelper.DTFunctionButtons.Remove:
                                        removeIndex = j;
                                        break;
                                    case DTGUIHelper.DTFunctionButtons.ShiftUp:
                                        moveUpIndex = j;
                                        break;
                                    case DTGUIHelper.DTFunctionButtons.ShiftDown:
                                        moveDownIndex = j;
                                        break;
                                    case DTGUIHelper.DTFunctionButtons.Play:
                                        MasterAudio.PreviewerInstance.Stop();
                                        MasterAudio.PreviewerInstance.PlayOneShot(aSong.clip, aSong.volume);
                                        break;
                                    case DTGUIHelper.DTFunctionButtons.Stop:
                                        MasterAudio.PreviewerInstance.clip = null;
                                        MasterAudio.PreviewerInstance.Stop();
                                        break;
                                }
                            }

                            if (addIndex.HasValue) {
                                var mus = new MusicSetting();
                                UndoHelper.RecordObjectPropertyForUndo(sounds, "add song");
                                aList.MusicSettings.Insert(addIndex.Value + 1, mus);
                            } else if (removeIndex.HasValue) {
                                if (aList.MusicSettings.Count <= 1) {
                                    DTGUIHelper.ShowAlert("You cannot delete the last clip. You do not have to use the clips though.");
                                } else {
                                    UndoHelper.RecordObjectPropertyForUndo(sounds, "delete song");
                                    aList.MusicSettings.RemoveAt(removeIndex.Value);
                                }
                            } else if (moveUpIndex.HasValue) {
                                var item = aList.MusicSettings[moveUpIndex.Value];

                                UndoHelper.RecordObjectPropertyForUndo(sounds, "shift up song");

                                aList.MusicSettings.Insert(moveUpIndex.Value - 1, item);
                                aList.MusicSettings.RemoveAt(moveUpIndex.Value + 1);
                            } else if (moveDownIndex.HasValue) {
                                var index = moveDownIndex.Value + 1;
                                var item = aList.MusicSettings[index];

                                UndoHelper.RecordObjectPropertyForUndo(sounds, "shift down song");

                                aList.MusicSettings.Insert(index - 1, item);
                                aList.MusicSettings.RemoveAt(index + 1);
                            }
                        }

                        switch (playlistButtonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            playlistToRemove = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Add:
                            playlistToInsertAt = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.ShiftUp:
                            playlistToMoveUp = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.ShiftDown:
                            playlistToMoveDown = i;
                            break;
                        }
                    }

                    if (playlistToRemove.HasValue) {
                        if (sounds.musicPlaylists.Count <= 1) {
                            DTGUIHelper.ShowAlert("You cannot delete the last Playlist. You do not have to use it though.");
                        } else {
                            UndoHelper.RecordObjectPropertyForUndo(sounds, "delete Playlist");

                            sounds.musicPlaylists.RemoveAt(playlistToRemove.Value);
                        }
                    }
                    if (playlistToInsertAt.HasValue) {
                        var pl = new MasterAudio.Playlist();
                        UndoHelper.RecordObjectPropertyForUndo(sounds, "add Playlist");
                        sounds.musicPlaylists.Insert(playlistToInsertAt.Value + 1, pl);
                    }
                    if (playlistToMoveUp.HasValue) {
                        var item = sounds.musicPlaylists[playlistToMoveUp.Value];
                        UndoHelper.RecordObjectPropertyForUndo(sounds, "shift up Playlist");
                        sounds.musicPlaylists.Insert(playlistToMoveUp.Value - 1, item);
                        sounds.musicPlaylists.RemoveAt(playlistToMoveUp.Value + 1);
                    }
                    if (playlistToMoveDown.HasValue) {
                        var index = playlistToMoveDown.Value + 1;
                        var item = sounds.musicPlaylists[index];

                        UndoHelper.RecordObjectPropertyForUndo(sounds, "shift down Playlist");

                        sounds.musicPlaylists.Insert(index - 1, item);
                        sounds.musicPlaylists.RemoveAt(index + 1);
                    }

                    EditorGUILayout.Separator();
                }
            } else {
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndHorizontal();
            }
        }
        // Music playlist End

        // Custom Events Start
        GUI.color = sounds.showCustomEvents ? activeClr : inactiveClr;
        EditorGUILayout.BeginHorizontal(EditorStyles.objectFieldThumb);
        isExp = EditorGUILayout.Toggle("Show Custom Events", sounds.showCustomEvents);
        if (isExp != sounds.showCustomEvents) {
            UndoHelper.RecordObjectPropertyForUndo(sounds, "toggle Show Custom Events");
            sounds.showCustomEvents = isExp;
        }
        EditorGUILayout.EndHorizontal();
        GUI.color = Color.white;

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

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

            if (sounds.customEvents.Count == 0) {
                DTGUIHelper.ShowColorWarning("*You currently have no custom events.");
            }

            EditorGUILayout.Separator();

            int? customEventToDelete = null;
            int? eventToRename = null;

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

                GUILayout.FlexibleSpace();
                if (Application.isPlaying) {
                    var receivers = MasterAudio.ReceiversForEvent(anEvent.EventName);

                    if (receivers.Count > 0) {
                        GUI.contentColor = Color.green;
                        if (GUILayout.Button("Select", EditorStyles.toolbarButton, GUILayout.Width(50))) {
                            Selection.objects = receivers.ToArray();
                        }
                        GUI.contentColor = Color.white;
                    }

                    GUI.contentColor = Color.yellow;
                    GUILayout.Label(string.Format("Receivers: {0}", receivers.Count));
                    GUI.contentColor = Color.white;
                } else {
                    var newName = GUILayout.TextField(anEvent.ProspectiveName, GUILayout.Width(170));
                    if (newName != anEvent.ProspectiveName) {
                        UndoHelper.RecordObjectPropertyForUndo(sounds, "change Proposed Event Name");
                        anEvent.ProspectiveName = newName;
                    }

                    var buttonPressed = DTGUIHelper.AddCustomEventDeleteIcon(true);

                    switch (buttonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            customEventToDelete = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Rename:
                            eventToRename = i;
                            break;
                    }
                }

                EditorGUILayout.EndHorizontal();
            }

            if (customEventToDelete.HasValue) {
                sounds.customEvents.RemoveAt(customEventToDelete.Value);
            }
            if (eventToRename.HasValue) {
                RenameEvent(sounds.customEvents[eventToRename.Value]);
            }
        }

        // Custom Events End

        EditorUtility.SetDirty(target);

        if (sounds.enableFastResponse) {
            this.Repaint();
        }

        //DrawDefaultInspector();
    }
    private void AddSongToPlaylist(MasterAudio.Playlist pList, AudioClip aClip)
    {
        var lastClip = pList.MusicSettings[pList.MusicSettings.Count - 1];

        MusicSetting mus;

        if (lastClip.clip == null) {
            mus = lastClip;
            mus.clip = aClip;
        } else {
            mus = new MusicSetting() {
                clip = aClip,
                volume = 1f,
                pitch = 1f,
                isExpanded = true
            };

            pList.MusicSettings.Add(mus);
        }
    }
Exemplo n.º 25
0
    /// <summary>
    /// This method will Stop the Playlist. 
    /// </summary>
    public void StopPlaylist(bool onlyFadingClip = false)
    {
        if (!Application.isPlaying)
        {
            return;
        }

        currentSong = null;
        if (!onlyFadingClip)
        {
            CeaseAudioSource(this.activeAudio);
        }

        CeaseAudioSource(this.transitioningAudio);
    }
    public override void OnInspectorGUI() {
        EditorGUIUtility.LookLikeControls();

        EditorGUI.indentLevel = 1;
        _isDirty = false;

        _creator = (DynamicSoundGroupCreator)target;

        var isInProjectView = DTGUIHelper.IsPrefabInProjectView(_creator);

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

        MasterAudio.Instance = null;
        var ma = MasterAudio.Instance;
        var maInScene = ma != null;

        if (maInScene) {
            _customEventNames = ma.CustomEventNames;
        }

        _previewer = _creator.gameObject;
        var allowPreview = !DTGUIHelper.IsPrefabInProjectView(_creator);

        var sliderIndicatorChars = 6;
        var sliderWidth = 40;

        if (MasterAudio.UseDbScaleForVolume) {
            sliderIndicatorChars = 9;
            sliderWidth = 56;
        }

        var busVoiceLimitList = new List<string> { MasterAudio.NoVoiceLimitName };

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

        var busList = new List<string> { MasterAudioGroup.NoBus, MasterAudioInspector.NewBusName, ExistingBus };

        var maxChars = 12;

        foreach (var t in _creator.groupBuses) {
            var bus = t;
            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

        if (MasterAudio.Instance == null) {
            var newLang = (SystemLanguage)EditorGUILayout.EnumPopup(new GUIContent("Preview Language", "This setting is only used (and visible) to choose the previewing language when there's no Master Audio prefab in the Scene (language settings are grabbed from there normally). This should only happen when you're using a Master Audio prefab from a previous Scene in persistent mode."), _creator.previewLanguage);
            if (newLang != _creator.previewLanguage) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Preview Language");
                _creator.previewLanguage = newLang;
            }
        }

        EditorGUILayout.Separator();

        var newAllow = (DynamicSoundGroupCreator.CreateItemsWhen)EditorGUILayout.EnumPopup("Items Created When?", _creator.reUseMode);
        if (newAllow != _creator.reUseMode) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Items Created When?");
            _creator.reUseMode = newAllow;
        }

        var newIgnore = EditorGUILayout.Toggle("Error On Duplicate Items", _creator.errorOnDuplicates);
        if (newIgnore != _creator.errorOnDuplicates) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Error On Duplicate Items");
            _creator.errorOnDuplicates = newIgnore;
        }
        if (_creator.errorOnDuplicates) {
            DTGUIHelper.ShowColorWarning("An error will be logged if your Dynamic items already exist in the MA prefab.");
        } else {
            DTGUIHelper.ShowLargeBarAlert("Dynamic items that already exist in the MA prefab will be ignored and not created.");
        }


        var newAwake = EditorGUILayout.Toggle("Auto-create Items", _creator.createOnAwake);
        if (newAwake != _creator.createOnAwake) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _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.ShowLargeBarAlert("You will need to call this object's CreateItems method manually to create the items.");
        }

        var newRemove = EditorGUILayout.Toggle("Auto-remove Items", _creator.removeGroupsOnSceneChange);
        if (newRemove != _creator.removeGroupsOnSceneChange) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Auto-remove Items");
            _creator.removeGroupsOnSceneChange = newRemove;
        }

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

        // custom event
        DTGUIHelper.StartGroupHeader();
        GUI.color = Color.white;
        var exp = EditorGUILayout.BeginToggleGroup("Fire 'Items Created' Event", _creator.itemsCreatedEventExpanded);
        if (exp != _creator.itemsCreatedEventExpanded) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle expand Fire 'Items Created' Event");
            _creator.itemsCreatedEventExpanded = exp;
        }
        GUI.color = Color.white;
        DTGUIHelper.EndGroupHeader();

        if (_creator.itemsCreatedEventExpanded) {
            EditorGUI.indentLevel = 0;
            DTGUIHelper.ShowColorWarning("When items are created, fire Custom Event below.");

            var existingIndex = _customEventNames.IndexOf(_creator.itemsCreatedCustomEvent);

            int? customEventIndex = null;

            var noEvent = false;
            var noMatch = false;

            if (existingIndex >= 1) {
                customEventIndex = EditorGUILayout.Popup("Custom Event Name", existingIndex, _customEventNames.ToArray());
                if (existingIndex == 1) {
                    noEvent = true;
                }
            } else if (existingIndex == -1 && _creator.itemsCreatedCustomEvent == MasterAudio.NoGroupName) {
                customEventIndex = EditorGUILayout.Popup("Custom Event Name", existingIndex, _customEventNames.ToArray());
            } else { // non-match
                noMatch = true;
                var newEventName = EditorGUILayout.TextField("Custom Event Name", _creator.itemsCreatedCustomEvent);
                if (newEventName != _creator.itemsCreatedCustomEvent) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Custom Event Name");
                    _creator.itemsCreatedCustomEvent = newEventName;
                }

                var newIndex = EditorGUILayout.Popup("All Custom Events", -1, _customEventNames.ToArray());
                if (newIndex >= 0) {
                    customEventIndex = newIndex;
                }
            }

            if (noEvent) {
                DTGUIHelper.ShowRedError("No Custom Event specified. This section will do nothing.");
            } else if (noMatch) {
                DTGUIHelper.ShowRedError("Custom Event found no match. Type in or choose one.");
            }

            if (customEventIndex.HasValue) {
                if (existingIndex != customEventIndex.Value) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Custom Event");
                }
                // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                if (customEventIndex.Value == -1) {
                    _creator.itemsCreatedCustomEvent = MasterAudio.NoGroupName;
                } else {
                    _creator.itemsCreatedCustomEvent = _customEventNames[customEventIndex.Value];
                }
            }
        }
        EditorGUILayout.EndToggleGroup();

        _groups = ScanForGroups();
        var groupNameList = GroupNameList;

        EditorGUI.indentLevel = 0;

        var state = _creator.showMusicDucking;
        var text = "Dynamic Music Ducking";

        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
        if (!state) {
            GUI.backgroundColor = DTGUIHelper.InactiveHeaderColor;
        } else {
            GUI.backgroundColor = DTGUIHelper.ActiveHeaderColor;
        }

        DTGUIHelper.AddSpaceForNonU5(2);

        GUILayout.BeginHorizontal();

#if UNITY_3_5_7
        if (!state) {
            text += " (Click to expand)";
        }
#else
        text = "<b><size=11>" + text + "</size></b>";
#endif
        if (state) {
            text = "\u25BC " + text;
        } else {
            text = "\u25BA " + text;
        }
        if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) {
            state = !state;
        }

        GUILayout.Space(2f);



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

        if (_creator.showMusicDucking) {
            DTGUIHelper.BeginGroupedControls();
            GUI.contentColor = DTGUIHelper.BrightButtonColor;
            EditorGUILayout.BeginHorizontal();

            GUILayout.Space(10);

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

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

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

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

            if (_creator.musicDuckingSounds.Count == 0) {
                DTGUIHelper.ShowLargeBarAlert("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;
                    }

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

                    GUI.contentColor = DTGUIHelper.BrightButtonColor;
                    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) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _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();
                    DTGUIHelper.EndGroupHeader();
                    DTGUIHelper.AddSpaceForNonU5(2);
                }

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

            DTGUIHelper.EndGroupedControls();
        }

        DTGUIHelper.ResetColors();


        DTGUIHelper.VerticalSpace(3);

        state = _creator.soundGroupsAreExpanded;
        text = "Dynamic Group Mixer";

        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
        if (!state) {
            GUI.backgroundColor = DTGUIHelper.InactiveHeaderColor;
        } else {
            GUI.backgroundColor = DTGUIHelper.ActiveHeaderColor;
        }

        GUILayout.BeginHorizontal();

#if UNITY_3_5_7
        if (!state) {
            text += " (Click to expand)";
        }
#else
        text = "<b><size=11>" + text + "</size></b>";
#endif
        if (state) {
            text = "\u25BC " + text;
        } else {
            text = "\u25BA " + text;
        }
        if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) {
            state = !state;
        }

        GUILayout.Space(2f);


        if (state != _creator.soundGroupsAreExpanded) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Dynamic Group Mixer");
            _creator.soundGroupsAreExpanded = state;
        }

        var applyTemplateToAll = false;
        EditorGUILayout.EndHorizontal();
        GUI.color = Color.white;

        if (_creator.soundGroupsAreExpanded) {
            DTGUIHelper.BeginGroupedControls();

            DTGUIHelper.StartGroupHeader();
            EditorGUILayout.LabelField("Group Control");

            EditorGUILayout.EndVertical();

            _audioSourceTemplateNames = new List<string>();

            foreach (var temp in _creator.audioSourceTemplates) {
                if (temp == null) {
                    continue;
                }
                _audioSourceTemplateNames.Add(temp.name);
            }

            var audTemplatesMissing = false;

            if (Directory.Exists(MasterAudio.AudioSourceTemplateFolder)) {
                var audioSrcTemplates = Directory.GetFiles(MasterAudio.AudioSourceTemplateFolder, "*.prefab").Length;
                if (audioSrcTemplates > _creator.audioSourceTemplates.Count) {
                    audTemplatesMissing = true;
                    DTGUIHelper.ShowLargeBarAlert("There's " + (audioSrcTemplates - _creator.audioSourceTemplates.Count) + " Audio Source Template(s) that aren't set up in this MA prefab. Locate them");
                    DTGUIHelper.ShowLargeBarAlert("in DarkTonic/MasterAudio/Sources/Prefabs/AudioSourceTemplates and drag them in below.");
                }
            }

            Event aEvent;
            if (audTemplatesMissing) {
                // create groups start
                EditorGUILayout.BeginVertical();
                aEvent = Event.current;

                GUI.color = DTGUIHelper.DragAreaColor;

                var dragArea = GUILayoutUtility.GetRect(0f, 35f, GUILayout.ExpandWidth(true));
                GUI.Box(dragArea, "Drag prefabs here from Project View to create Group Templates!");

                GUI.color = Color.white;

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

                        DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

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

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

                                AddAudioSourceTemplate(temp);
                            }
                        }
                        Event.current.Use();
                        break;
                }
                EditorGUILayout.EndVertical();
                // create groups end
            }

            if (_audioSourceTemplateNames.Count == 0) {
                DTGUIHelper.ShowRedError("You have no Audio Source Templates. Drag them in to create them.");
            } else {
                var audSrcTemplateIndex = _audioSourceTemplateNames.IndexOf(_creator.audioSourceTemplateName);
                if (audSrcTemplateIndex < 0) {
                    audSrcTemplateIndex = 0;
                    _creator.audioSourceTemplateName = _audioSourceTemplateNames[0];
                }

                var newIndex = EditorGUILayout.Popup("Audio Source Template", audSrcTemplateIndex, _audioSourceTemplateNames.ToArray());
                if (newIndex != audSrcTemplateIndex) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Audio Source Template");
                    _creator.audioSourceTemplateName = _audioSourceTemplateNames[newIndex];
                }
            }

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

            var bulkMode = DTGUIHelper.GetRestrictedAudioLocation("Variation Create Mode", _creator.bulkVariationMode);
            if (bulkMode != _creator.bulkVariationMode) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Variation Mode");
                _creator.bulkVariationMode = bulkMode;
            }

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

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

                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);
                            });

                            foreach (var aClip in clips) {
                                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 (_groups.Count == 0) {
                DTGUIHelper.ShowLargeBarAlert("You currently have no Dynamic Sound Groups created.");
            }

            int? indexToDelete = null;
            DTGUIHelper.ResetColors();

            GUI.color = Color.white;
            int? busToCreate = null;
            var isExistingBus = false;

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

                var groupDirty = false;

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

                GUILayout.FlexibleSpace();

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

                GUI.contentColor = Color.white;
                GUI.color = DTGUIHelper.BrightButtonColor;

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

                if (aGroup.busIndex != busIndex && busIndex != 1) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref groupDirty, 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 = DTGUIHelper.BrightTextColor;
                GUILayout.TextField(DTGUIHelper.DisplayVolumeNumber(aGroup.groupMasterVolume, sliderIndicatorChars), sliderIndicatorChars, EditorStyles.miniLabel, GUILayout.Width(sliderWidth));

                var newVol = DTGUIHelper.DisplayVolumeField(aGroup.groupMasterVolume, DTGUIHelper.VolumeFieldType.DynamicMixerGroup, MasterAudio.MixerWidthMode.Normal);
                if (newVol != aGroup.groupMasterVolume) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref groupDirty, aGroup, "change Group Volume");
                    aGroup.groupMasterVolume = newVol;
                }

                GUI.contentColor = Color.white;

                var buttonPressed = DTGUIHelper.AddDynamicGroupButtons(_creator);
                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 (groupDirty) {
                    EditorUtility.SetDirty(aGroup);
                }
            }

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

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

            EditorGUILayout.Separator();
            EditorGUILayout.BeginHorizontal();

            GUILayout.Space(10);

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

                foreach (var aGroup in _groups) {
                    aGroup.groupMasterVolume = 1f;
                }
            }

            if (_creator.audioSourceTemplates.Count > 0 && !Application.isPlaying && _creator.transform.childCount > 0) {
                GUILayout.Space(10);

                GUI.contentColor = DTGUIHelper.BrightButtonColor;

                if (GUILayout.Button("Apply Audio Source Template to All", EditorStyles.toolbarButton, GUILayout.Width(190))) {
                    applyTemplateToAll = true;
                }

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

            //buses
            if (_creator.groupBuses.Count > 0) {
                DTGUIHelper.VerticalSpace(3);

                var voiceLimitedBuses = _creator.groupBuses.FindAll(delegate(GroupBus obj) {
                    return obj.voiceLimit >= 0;
                });

                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("Bus Control", GUILayout.Width(100));
                if (voiceLimitedBuses.Count > 0) {
                    GUILayout.FlexibleSpace();
                    GUILayout.Label("Stop Oldest", GUILayout.Width(100));
                    GUILayout.Space(234);
                }
                EditorGUILayout.EndHorizontal();

                int? busToDelete = null;

                for (var i = 0; i < _creator.groupBuses.Count; i++) {
                    DTGUIHelper.StartGroupHeader(1, false);
                    var aBus = _creator.groupBuses[i];

                    var showingMixer = _creator.ShouldShowUnityAudioMixerGroupAssignments && !aBus.isExisting;

                    if (showingMixer) {
                        EditorGUILayout.BeginVertical();
                        EditorGUILayout.BeginHorizontal();
                    } else {
                        EditorGUILayout.BeginHorizontal();
                    }

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

                    GUILayout.FlexibleSpace();

                    if (!aBus.isExisting) {
                        if (voiceLimitedBuses.Contains(aBus)) {
                            GUI.color = DTGUIHelper.BrightButtonColor;
                            var newMono = GUILayout.Toggle(aBus.stopOldest, new GUIContent("", "Stop Oldest"));
                            if (newMono != aBus.stopOldest) {
                                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Stop Oldest");
                                aBus.stopOldest = newMono;
                            }
                        }

                        GUI.color = Color.white;
                        GUILayout.Label("Voices");
                        GUI.color = DTGUIHelper.BrightButtonColor;

                        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) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Bus Voice Limit");
                            aBus.voiceLimit = busVoiceLimitIndex <= 0 ? -1 : busVoiceLimitIndex;
                        }

                        GUI.color = DTGUIHelper.BrightTextColor;

                        GUILayout.TextField(DTGUIHelper.DisplayVolumeNumber(aBus.volume, sliderIndicatorChars), sliderIndicatorChars, EditorStyles.miniLabel, GUILayout.Width(sliderWidth));

                        GUI.color = Color.white;
                        var newBusVol = DTGUIHelper.DisplayVolumeField(aBus.volume, DTGUIHelper.VolumeFieldType.Bus, MasterAudio.MixerWidthMode.Normal);
                        if (newBusVol != aBus.volume) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _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();
                    EditorGUILayout.EndVertical();
#if UNITY_5
                    if (!showingMixer) {
                        //EditorGUILayout.EndVertical();
                        continue;
                    }

                    var newChan = (AudioMixerGroup)EditorGUILayout.ObjectField(aBus.mixerChannel, typeof(AudioMixerGroup), false);
                    if (newChan != aBus.mixerChannel) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Bus Mixer Group");
                        aBus.mixerChannel = newChan;
                    }
                    EditorGUILayout.EndVertical();
#endif
                    //EditorGUILayout.EndVertical();
                    DTGUIHelper.AddSpaceForNonU5(2);
                }

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

#if UNITY_5
                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(6);

                GUI.contentColor = DTGUIHelper.BrightButtonColor;
                var buttonText = "Show Unity Mixer Groups";
                if (_creator.showUnityMixerGroupAssignment) {
                    buttonText = "Hide Unity Mixer Groups";
                }
                if (GUILayout.Button(new GUIContent(buttonText), EditorStyles.toolbarButton, GUILayout.Width(140))) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, buttonText);
                    _creator.showUnityMixerGroupAssignment = !_creator.showUnityMixerGroupAssignment;
                }

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

            DTGUIHelper.EndGroupedControls();
        }

        if (applyTemplateToAll) {
            AudioUndoHelper.RecordObjectsForUndo(_groups.ToArray(), "Apply Audio Source Template to All");

            foreach (var myGroup in _groups) {
                for (var v = 0; v < myGroup.transform.childCount; v++) {
#if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
                        Debug.LogError("This feature requires Unity 4 or higher.");
#else
                    var aVar = myGroup.transform.GetChild(v);
                    var oldAudio = aVar.GetComponent<AudioSource>();
                    CopyFromAudioSourceTemplate(_creator, oldAudio, true);
#endif
                }
            }
        }

        DTGUIHelper.VerticalSpace(3);
        DTGUIHelper.ResetColors();

        // Music playlist Start		
        EditorGUILayout.BeginHorizontal();
        EditorGUI.indentLevel = 0;  // Space will handle this for the header

        state = _creator.playListExpanded;
        text = "Dynamic Playlist Settings";

        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
        if (!state) {
            GUI.backgroundColor = DTGUIHelper.InactiveHeaderColor;
        } else {
            GUI.backgroundColor = DTGUIHelper.ActiveHeaderColor;
        }

        GUILayout.BeginHorizontal();

#if UNITY_3_5_7
        if (!state) {
            text += " (Click to expand)";
        }
#else
        text = "<b><size=11>" + text + "</size></b>";
#endif
        if (state) {
            text = "\u25BC " + text;
        } else {
            text = "\u25BA " + text;
        }
        if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) {
            state = !state;
        }

        GUILayout.Space(2f);


        if (state != _creator.playListExpanded) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Dynamic Playlist Settings");
            _creator.playListExpanded = state;
        }

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

        EditorGUILayout.EndHorizontal();

        if (_creator.playListExpanded) {
            DTGUIHelper.BeginGroupedControls();
            EditorGUI.indentLevel = 0;  // Space will handle this for the header

            if (_creator.musicPlaylists.Count == 0) {
                DTGUIHelper.ShowLargeBarAlert("You currently have no Playlists set up.");
            }

            EditorGUI.indentLevel = 1;
            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
            var oldPlayExpanded = DTGUIHelper.Foldout(_creator.playlistEditorExp, string.Format("Playlists ({0})", _creator.musicPlaylists.Count));
            if (oldPlayExpanded != _creator.playlistEditorExp) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Playlists");
                _creator.playlistEditorExp = oldPlayExpanded;
            }

            EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(100));

            const string buttonText = "Click to add new Playlist at the end";

            // Add button - Process presses later
            GUI.contentColor = DTGUIHelper.BrightButtonColor;
            var addPressed = GUILayout.Button(new GUIContent("Add", buttonText),
                EditorStyles.toolbarButton);

            GUI.contentColor = DTGUIHelper.BrightButtonColor;
            var content = new GUIContent("Collapse", "Click to collapse all");
            var masterCollapse = GUILayout.Button(content, EditorStyles.toolbarButton);

            content = new GUIContent("Expand", "Click to expand all");
            var masterExpand = GUILayout.Button(content, EditorStyles.toolbarButton);
            if (masterExpand) {
                ExpandCollapseAllPlaylists(true);
            }
            if (masterCollapse) {
                ExpandCollapseAllPlaylists(false);
            }
            GUI.contentColor = Color.white;
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndHorizontal();

            if (_creator.playlistEditorExp) {
                int? playlistToRemove = null;
                int? playlistToInsertAt = null;
                int? playlistToMoveUp = null;
                int? playlistToMoveDown = null;

                for (var i = 0; i < _creator.musicPlaylists.Count; i++) {
                    DTGUIHelper.StartGroupHeader();

                    var aList = _creator.musicPlaylists[i];

                    EditorGUI.indentLevel = 1;
                    EditorGUILayout.BeginHorizontal();
                    aList.isExpanded = DTGUIHelper.Foldout(aList.isExpanded, "Playlist: " + aList.playlistName);

                    var playlistButtonPressed = DTGUIHelper.AddFoldOutListItemButtons(i, _creator.musicPlaylists.Count, "playlist", false, true);

                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndVertical();

                    if (aList.isExpanded) {
                        EditorGUI.indentLevel = 0;
                        var newPlaylist = EditorGUILayout.TextField("Name", aList.playlistName);
                        if (newPlaylist != aList.playlistName) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Name");
                            aList.playlistName = newPlaylist;
                        }

                        var crossfadeMode = (MasterAudio.Playlist.CrossfadeTimeMode)EditorGUILayout.EnumPopup("Crossfade Mode", aList.crossfadeMode);
                        if (crossfadeMode != aList.crossfadeMode) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Crossfade Mode");
                            aList.crossfadeMode = crossfadeMode;
                        }
                        if (aList.crossfadeMode == MasterAudio.Playlist.CrossfadeTimeMode.Override) {
                            var newCf = EditorGUILayout.Slider("Crossfade time (sec)", aList.crossFadeTime, 0f, 10f);
                            // ReSharper disable once CompareOfFloatsByEqualityOperator
                            if (newCf != aList.crossFadeTime) {
                                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Crossfade time (sec)");
                                aList.crossFadeTime = newCf;
                            }
                        }

                        var newFadeIn = EditorGUILayout.Toggle("Fade In First Song", aList.fadeInFirstSong);
                        if (newFadeIn != aList.fadeInFirstSong) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Fade In First Song");
                            aList.fadeInFirstSong = newFadeIn;
                        }

                        var newFadeOut = EditorGUILayout.Toggle("Fade Out Last Song", aList.fadeOutLastSong);
                        if (newFadeOut != aList.fadeOutLastSong) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Fade Out Last Song");
                            aList.fadeOutLastSong = newFadeOut;
                        }

                        var newTransType = (MasterAudio.SongFadeInPosition)EditorGUILayout.EnumPopup("Song Transition Type", aList.songTransitionType);
                        if (newTransType != aList.songTransitionType) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Song Transition Type");
                            aList.songTransitionType = newTransType;
                        }
                        if (aList.songTransitionType == MasterAudio.SongFadeInPosition.SynchronizeClips) {
                            DTGUIHelper.ShowColorWarning("All clips must be of exactly the same length in this mode.");
                        }

                        EditorGUI.indentLevel = 0;
                        var newBulkMode = DTGUIHelper.GetRestrictedAudioLocation("Clip Create Mode", aList.bulkLocationMode);
                        if (newBulkMode != aList.bulkLocationMode) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Bulk Clip Mode");
                            aList.bulkLocationMode = newBulkMode;
                        }

                        var playlistHasResource = false;
                        foreach (var t in aList.MusicSettings) {
                            if (t.audLocation != MasterAudio.AudioLocation.ResourceFile) {
                                continue;
                            }
                            playlistHasResource = true;
                            break;
                        }

                        if (MasterAudio.HasAsyncResourceLoaderFeature() && playlistHasResource) {
                            if (!maInScene || !ma.resourceClipsAllLoadAsync) {
                                var newAsync = EditorGUILayout.Toggle(new GUIContent("Load Resources Async", "Checking this means Resource files in this Playlist will be loaded asynchronously."), aList.resourceClipsAllLoadAsync);
                                if (newAsync != aList.resourceClipsAllLoadAsync) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Load Resources Async");
                                    aList.resourceClipsAllLoadAsync = newAsync;
                                }
                            }
                        }
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.Space(10);
                        GUI.contentColor = DTGUIHelper.BrightButtonColor;
                        if (GUILayout.Button(new GUIContent("Eq. Song Volumes"), EditorStyles.toolbarButton, GUILayout.Width(110))) {
                            EqualizePlaylistVolumes(aList.MusicSettings);
                        }

                        var hasExpanded = false;
                        foreach (var t in aList.MusicSettings) {
                            if (!t.isExpanded) {
                                continue;
                            }
                            hasExpanded = true;
                            break;
                        }

                        var theButtonText = hasExpanded ? "Collapse All" : "Expand All";

                        GUILayout.Space(10);
                        GUI.contentColor = DTGUIHelper.BrightButtonColor;
                        if (GUILayout.Button(new GUIContent(theButtonText), EditorStyles.toolbarButton, GUILayout.Width(100))) {
                            ExpandCollapseSongs(aList, !hasExpanded);
                        }
                        GUILayout.Space(10);
                        if (GUILayout.Button(new GUIContent("Sort Alpha"), EditorStyles.toolbarButton, GUILayout.Width(100))) {
                            SortSongsAlpha(aList);
                        }

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

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

                        GUI.color = DTGUIHelper.DragAreaColor;

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

                        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;
                                        }

                                        AddSongToPlaylist(aList, aClip);
                                    }
                                }
                                Event.current.Use();
                                break;
                        }
                        EditorGUILayout.EndVertical();

                        EditorGUI.indentLevel = 2;

                        int? addIndex = null;
                        int? removeIndex = null;
                        int? moveUpIndex = null;
                        int? moveDownIndex = null;

                        if (aList.MusicSettings.Count == 0) {
                            EditorGUI.indentLevel = 0;
                            DTGUIHelper.ShowLargeBarAlert("You currently have no songs in this Playlist.");
                        }

                        EditorGUI.indentLevel = 0;

                        for (var j = 0; j < aList.MusicSettings.Count; j++) {
                            DTGUIHelper.StartGroupHeader(1);
                            var aSong = aList.MusicSettings[j];
                            var clipName = "Empty";
                            switch (aSong.audLocation) {
                                case MasterAudio.AudioLocation.Clip:
                                    if (aSong.clip != null) {
                                        clipName = aSong.clip.name;
                                    }
                                    break;
                                case MasterAudio.AudioLocation.ResourceFile:
                                    if (!string.IsNullOrEmpty(aSong.resourceFileName)) {
                                        clipName = aSong.resourceFileName;
                                    }
                                    break;
                            }
                            EditorGUILayout.BeginHorizontal();
                            EditorGUI.indentLevel = 1;

                            aSong.songName = aSong.alias;
                            if (!string.IsNullOrEmpty(clipName) && string.IsNullOrEmpty(aSong.songName)) {
                                switch (aSong.audLocation) {
                                    case MasterAudio.AudioLocation.Clip:
                                        aSong.songName = clipName;
                                        break;
                                    case MasterAudio.AudioLocation.ResourceFile:
                                        aSong.songName = clipName;
                                        break;
                                }
                            }

                            var newSongExpanded = DTGUIHelper.Foldout(aSong.isExpanded, aSong.songName);
                            if (newSongExpanded != aSong.isExpanded) {
                                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Song expand");
                                aSong.isExpanded = newSongExpanded;
                            }

                            var songButtonPressed = DTGUIHelper.AddFoldOutListItemButtons(j, aList.MusicSettings.Count, "clip", false, true, allowPreview);
                            EditorGUILayout.EndHorizontal();
                            EditorGUILayout.EndVertical();

                            if (aSong.isExpanded) {
                                EditorGUI.indentLevel = 0;

                                var newName = EditorGUILayout.TextField(new GUIContent("Song Alias (optional)", "When you 'Play song by name', Song Aliases will be searched first before audio file name."), aSong.alias);
                                if (newName != aSong.alias) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Song Id");
                                    aSong.alias = newName;
                                }

                                var oldLocation = aSong.audLocation;
                                var newClipSource = DTGUIHelper.GetRestrictedAudioLocation("Audio Origin", aSong.audLocation);
                                if (newClipSource != aSong.audLocation) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Audio Origin");
                                    aSong.audLocation = newClipSource;
                                }

                                switch (aSong.audLocation) {
                                    case MasterAudio.AudioLocation.Clip:
                                        var newClip = (AudioClip)EditorGUILayout.ObjectField("Audio Clip", aSong.clip, typeof(AudioClip), true);
                                        if (newClip != aSong.clip) {
                                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Clip");
                                            aSong.clip = newClip;
                                            var cName = newClip == null ? "Empty" : newClip.name;
                                            aSong.songName = cName;
                                        }
                                        break;
                                    case MasterAudio.AudioLocation.ResourceFile:
                                        if (oldLocation != aSong.audLocation) {
                                            if (aSong.clip != null) {
                                                Debug.Log("Audio clip removed to prevent unnecessary memory usage on Resource file Playlist clip.");
                                            }
                                            aSong.clip = null;
                                            aSong.songName = string.Empty;
                                        }

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

                                        GUI.color = DTGUIHelper.DragAreaColor;
                                        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;
                                                        }

                                                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Resource Filename");

                                                        var unused = false;
                                                        var resourceFileName = DTGUIHelper.GetResourcePath(aClip, ref unused);
                                                        if (string.IsNullOrEmpty(resourceFileName)) {
                                                            resourceFileName = aClip.name;
                                                        }

                                                        aSong.resourceFileName = resourceFileName;
                                                        aSong.songName = aClip.name;
                                                    }
                                                }
                                                Event.current.Use();
                                                break;
                                        }
                                        EditorGUILayout.EndVertical();

                                        var newFilename = EditorGUILayout.TextField("Resource Filename", aSong.resourceFileName);
                                        if (newFilename != aSong.resourceFileName) {
                                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Resource Filename");
                                            aSong.resourceFileName = newFilename;
                                        }

                                        break;
                                }

                                var newVol = DTGUIHelper.DisplayVolumeField(aSong.volume, DTGUIHelper.VolumeFieldType.None, MasterAudio.MixerWidthMode.Normal, 0f, true);
                                if (newVol != aSong.volume) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Volume");
                                    aSong.volume = newVol;
                                }

                                var newPitch = DTGUIHelper.DisplayPitchField(aSong.pitch);
                                if (newPitch != aSong.pitch) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Pitch");
                                    aSong.pitch = newPitch;
                                }

                                if (aList.songTransitionType == MasterAudio.SongFadeInPosition.SynchronizeClips) {
                                    DTGUIHelper.ShowLargeBarAlert("All songs must loop in Synchronized Playlists when crossfade time is not zero. Auto-advance is disabled.");
                                } else {
                                    var newLoop = EditorGUILayout.Toggle("Loop Clip", aSong.isLoop);
                                    if (newLoop != aSong.isLoop) {
                                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Loop Clip");
                                        aSong.isLoop = newLoop;
                                    }
                                }

                                if (aList.songTransitionType == MasterAudio.SongFadeInPosition.NewClipFromBeginning) {
                                    var newStart = EditorGUILayout.FloatField("Start Time (seconds)", aSong.customStartTime, GUILayout.Width(300));
                                    if (newStart < 0) {
                                        newStart = 0f;
                                    }
                                    if (newStart != aSong.customStartTime) {
                                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Start Time (seconds)");
                                        aSong.customStartTime = newStart;
                                    }
                                }


                                EditorGUI.indentLevel = 0;
                                exp = EditorGUILayout.BeginToggleGroup("Song Started Event", aSong.songStartedEventExpanded);
                                if (exp != aSong.songStartedEventExpanded) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle expand Song Started Event");
                                    aSong.songStartedEventExpanded = exp;
                                }
                                GUI.color = Color.white;

                                if (aSong.songStartedEventExpanded) {
                                    EditorGUI.indentLevel = 1;
                                    DTGUIHelper.ShowColorWarning("When song starts, fire Custom Event below.");

                                    if (maInScene) {
                                        var existingIndex = _customEventNames.IndexOf(aSong.songStartedCustomEvent);

                                        int? customEventIndex = null;

                                        var noEvent = false;
                                        var noMatch = false;

                                        if (existingIndex >= 1) {
                                            customEventIndex = EditorGUILayout.Popup("Custom Event Name", existingIndex, _customEventNames.ToArray());
                                            if (existingIndex == 1) {
                                                noEvent = true;
                                            }
                                        } else if (existingIndex == -1 && aSong.songStartedCustomEvent == MasterAudio.NoGroupName) {
                                            customEventIndex = EditorGUILayout.Popup("Custom Event Name", existingIndex, _customEventNames.ToArray());
                                        } else { // non-match
                                            noMatch = true;
                                            var newEventName = EditorGUILayout.TextField("Custom Event Name", aSong.songStartedCustomEvent);
                                            if (newEventName != aSong.songStartedCustomEvent) {
                                                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Custom Event Name");
                                                aSong.songStartedCustomEvent = newEventName;
                                            }

                                            var newIndex = EditorGUILayout.Popup("All Custom Events", -1, _customEventNames.ToArray());
                                            if (newIndex >= 0) {
                                                customEventIndex = newIndex;
                                            }
                                        }

                                        if (noEvent) {
                                            DTGUIHelper.ShowRedError("No Custom Event specified. This section will do nothing.");
                                        } else if (noMatch) {
                                            DTGUIHelper.ShowRedError("Custom Event found no match. Type in or choose one.");
                                        }

                                        if (customEventIndex.HasValue) {
                                            if (existingIndex != customEventIndex.Value) {
                                                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Custom Event");
                                            }
                                            // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                                            if (customEventIndex.Value == -1) {
                                                aSong.songStartedCustomEvent = MasterAudio.NoGroupName;
                                            } else {
                                                aSong.songStartedCustomEvent = _customEventNames[customEventIndex.Value];
                                            }
                                        }
                                    } else {
                                        var newCustomEvent = EditorGUILayout.TextField("Custom Event Name", aSong.songStartedCustomEvent);
                                        if (newCustomEvent != aSong.songStartedCustomEvent) {
                                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "Custom Event Name");
                                            aSong.songStartedCustomEvent = newCustomEvent;
                                        }
                                    }
                                }
                                EditorGUILayout.EndToggleGroup();

                                EditorGUI.indentLevel = 0;
                                exp = EditorGUILayout.BeginToggleGroup("Song Changed Event", aSong.songChangedEventExpanded);
                                if (exp != aSong.songChangedEventExpanded) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle expand Song Changed Event");
                                    aSong.songChangedEventExpanded = exp;
                                }
                                GUI.color = Color.white;

                                if (aSong.songChangedEventExpanded) {
                                    EditorGUI.indentLevel = 1;
                                    DTGUIHelper.ShowColorWarning("When song changes to another, fire Custom Event below.");
                                    DTGUIHelper.ShowLargeBarAlert("If you are using gapless transitions, Song Changed Event cannot be used.");

                                    if (maInScene) {
                                        var existingIndex = _customEventNames.IndexOf(aSong.songChangedCustomEvent);

                                        int? customEventIndex = null;


                                        var noEvent = false;
                                        var noMatch = false;

                                        if (existingIndex >= 1) {
                                            customEventIndex = EditorGUILayout.Popup("Custom Event Name", existingIndex, _customEventNames.ToArray());
                                            if (existingIndex == 1) {
                                                noEvent = true;
                                            }
                                        } else if (existingIndex == -1 && aSong.songChangedCustomEvent == MasterAudio.NoGroupName) {
                                            customEventIndex = EditorGUILayout.Popup("Custom Event Name", existingIndex, _customEventNames.ToArray());
                                        } else { // non-match
                                            noMatch = true;
                                            var newEventName = EditorGUILayout.TextField("Custom Event Name", aSong.songChangedCustomEvent);
                                            if (newEventName != aSong.songChangedCustomEvent) {
                                                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Custom Event Name");
                                                aSong.songChangedCustomEvent = newEventName;
                                            }

                                            var newIndex = EditorGUILayout.Popup("All Custom Events", -1, _customEventNames.ToArray());
                                            if (newIndex >= 0) {
                                                customEventIndex = newIndex;
                                            }
                                        }

                                        if (noEvent) {
                                            DTGUIHelper.ShowRedError("No Custom Event specified. This section will do nothing.");
                                        } else if (noMatch) {
                                            DTGUIHelper.ShowRedError("Custom Event found no match. Type in or choose one.");
                                        }

                                        if (customEventIndex.HasValue) {
                                            if (existingIndex != customEventIndex.Value) {
                                                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Custom Event");
                                            }
                                            // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                                            if (customEventIndex.Value == -1) {
                                                aSong.songChangedCustomEvent = MasterAudio.NoGroupName;
                                            } else {
                                                aSong.songChangedCustomEvent = _customEventNames[customEventIndex.Value];
                                            }
                                        }
                                    } else {
                                        var newCustomEvent = EditorGUILayout.TextField("Custom Event Name", aSong.songChangedCustomEvent);
                                        if (newCustomEvent != aSong.songChangedCustomEvent) {
                                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "Custom Event Name");
                                            aSong.songChangedCustomEvent = newCustomEvent;
                                        }
                                    }
                                }
                                EditorGUILayout.EndToggleGroup();
                            }

                            switch (songButtonPressed) {
                                case DTGUIHelper.DTFunctionButtons.Add:
                                    addIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.Remove:
                                    removeIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.ShiftUp:
                                    moveUpIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.ShiftDown:
                                    moveDownIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.Play:
                                    StopPreviewer();
                                    switch (aSong.audLocation) {
                                        case MasterAudio.AudioLocation.Clip:
                                            GetPreviewer().PlayOneShot(aSong.clip, aSong.volume);
                                            break;
                                        case MasterAudio.AudioLocation.ResourceFile:
                                            GetPreviewer().PlayOneShot(Resources.Load(aSong.resourceFileName) as AudioClip, aSong.volume);
                                            break;
                                    }
                                    break;
                                case DTGUIHelper.DTFunctionButtons.Stop:
                                    GetPreviewer().clip = null;
                                    StopPreviewer();
                                    break;
                            }

                            EditorGUILayout.EndVertical();
                            DTGUIHelper.AddSpaceForNonU5(2);
                        }

                        if (addIndex.HasValue) {
                            var mus = new MusicSetting();
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "add song");
                            aList.MusicSettings.Insert(addIndex.Value + 1, mus);
                        } else if (removeIndex.HasValue) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "delete song");
                            aList.MusicSettings.RemoveAt(removeIndex.Value);
                        } else if (moveUpIndex.HasValue) {
                            var item = aList.MusicSettings[moveUpIndex.Value];

                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "shift up song");

                            aList.MusicSettings.Insert(moveUpIndex.Value - 1, item);
                            aList.MusicSettings.RemoveAt(moveUpIndex.Value + 1);
                        } else if (moveDownIndex.HasValue) {
                            var index = moveDownIndex.Value + 1;
                            var item = aList.MusicSettings[index];

                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "shift down song");

                            aList.MusicSettings.Insert(index - 1, item);
                            aList.MusicSettings.RemoveAt(index + 1);
                        }
                    }

                    switch (playlistButtonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            playlistToRemove = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Add:
                            playlistToInsertAt = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.ShiftUp:
                            playlistToMoveUp = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.ShiftDown:
                            playlistToMoveDown = i;
                            break;
                    }

                    EditorGUILayout.EndVertical();
                    DTGUIHelper.AddSpaceForNonU5(4);
                }


                if (playlistToRemove.HasValue) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "delete Playlist");

                    _creator.musicPlaylists.RemoveAt(playlistToRemove.Value);
                }
                if (playlistToInsertAt.HasValue) {
                    var pl = new MasterAudio.Playlist();
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "add Playlist");
                    _creator.musicPlaylists.Insert(playlistToInsertAt.Value + 1, pl);
                }
                if (playlistToMoveUp.HasValue) {
                    var item = _creator.musicPlaylists[playlistToMoveUp.Value];
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "shift up Playlist");
                    _creator.musicPlaylists.Insert(playlistToMoveUp.Value - 1, item);
                    _creator.musicPlaylists.RemoveAt(playlistToMoveUp.Value + 1);
                }
                if (playlistToMoveDown.HasValue) {
                    var index = playlistToMoveDown.Value + 1;
                    var item = _creator.musicPlaylists[index];

                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "shift down Playlist");

                    _creator.musicPlaylists.Insert(index - 1, item);
                    _creator.musicPlaylists.RemoveAt(index + 1);
                }
            }

            if (addPressed) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "add Playlist");
                _creator.musicPlaylists.Add(new MasterAudio.Playlist());
            }

            DTGUIHelper.EndGroupedControls();
        }
        // Music playlist End

        EditorGUI.indentLevel = 0;
        // Show Custom Events

        DTGUIHelper.VerticalSpace(3);
        DTGUIHelper.ResetColors();

        state = _creator.showCustomEvents;
        text = "Dynamic Custom Events";

        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
        if (!state) {
            GUI.backgroundColor = DTGUIHelper.InactiveHeaderColor;
        } else {
            GUI.backgroundColor = DTGUIHelper.ActiveHeaderColor;
        }

        GUILayout.BeginHorizontal();

#if UNITY_3_5_7
        if (!state) {
            text += " (Click to expand)";
        }
#else
        text = "<b><size=11>" + text + "</size></b>";
#endif
        if (state) {
            text = "\u25BC " + text;
        } else {
            text = "\u25BA " + text;
        }
        if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) {
            state = !state;
        }

        GUILayout.Space(2f);

        if (_creator.showCustomEvents != state) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle Dynamic Custom Events");
            _creator.showCustomEvents = state;
        }

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

        if (_creator.showCustomEvents) {
            DTGUIHelper.BeginGroupedControls();
            var newEvent = EditorGUILayout.TextField("New Event Name", _creator.newEventName);
            if (newEvent != _creator.newEventName) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change New Event Name");
                _creator.newEventName = newEvent;
            }

            GUI.contentColor = DTGUIHelper.BrightButtonColor;

            EditorGUILayout.BeginHorizontal();

            GUILayout.Space(10);
            if (GUILayout.Button("Create New Event", EditorStyles.toolbarButton, GUILayout.Width(100))) {
                CreateCustomEvent(_creator.newEventName);
            }

            GUILayout.Space(10);
            GUI.contentColor = DTGUIHelper.BrightButtonColor;

            var hasExpanded = false;
            foreach (var t in _creator.customEventsToCreate) {
                if (!t.eventExpanded) {
                    continue;
                }
                hasExpanded = true;
                break;
            }

            var buttonText = hasExpanded ? "Collapse All" : "Expand All";

            if (GUILayout.Button(buttonText, EditorStyles.toolbarButton, GUILayout.Width(100))) {
                ExpandCollapseCustomEvents(!hasExpanded);
            }
            GUILayout.Space(10);
            if (GUILayout.Button("Sort Alpha", EditorStyles.toolbarButton, GUILayout.Width(100))) {
                SortCustomEvents();
            }

            GUI.contentColor = Color.white;

            EditorGUILayout.EndHorizontal();

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

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

            for (var i = 0; i < _creator.customEventsToCreate.Count; i++) {
                DTGUIHelper.AddSpaceForNonU5(2);
                DTGUIHelper.StartGroupHeader();
                EditorGUI.indentLevel = 1;
                var anEvent = _creator.customEventsToCreate[i];

                EditorGUILayout.BeginHorizontal();
                exp = DTGUIHelper.Foldout(anEvent.eventExpanded, anEvent.EventName);
                if (exp != anEvent.eventExpanded) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "toggle expand Custom Event");
                    anEvent.eventExpanded = exp;
                }

                GUILayout.FlexibleSpace();
                var newName = GUILayout.TextField(anEvent.ProspectiveName, GUILayout.Width(170));
                if (newName != anEvent.ProspectiveName) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Proposed Event Name");
                    anEvent.ProspectiveName = newName;
                }

                var buttonPressed = DTGUIHelper.AddDeleteIcon(true, "Custom Event");

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

                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndVertical();

                if (!anEvent.eventExpanded) {
                    EditorGUILayout.EndVertical();
                    continue;
                }

                EditorGUI.indentLevel = 0;
                var rcvMode = (MasterAudio.CustomEventReceiveMode)EditorGUILayout.EnumPopup("Send To Receivers", anEvent.eventReceiveMode);
                if (rcvMode != anEvent.eventReceiveMode) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Send To Receivers");
                    anEvent.eventReceiveMode = rcvMode;
                }

                if (rcvMode == MasterAudio.CustomEventReceiveMode.WhenDistanceLessThan || rcvMode == MasterAudio.CustomEventReceiveMode.WhenDistanceMoreThan) {
                    var newDist = EditorGUILayout.Slider("Distance Threshold", anEvent.distanceThreshold, 0f, float.MaxValue);
                    if (newDist != anEvent.distanceThreshold) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _creator, "change Distance Threshold");
                        anEvent.distanceThreshold = newDist;
                    }
                }

                EditorGUILayout.EndVertical();
            }

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

            DTGUIHelper.EndGroupedControls();
        }

        // End Show Custom Events

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

        //DrawDefaultInspector();
    }
Exemplo n.º 27
0
    private void PlaySong(MusicSetting setting)
    {
        AudioSource audioClip;
        AudioSource transClip;

        if (activeAudio == null)
        {
            Debug.LogError("PlaylistController prefab is not in your scene. Cannot play a song.");
            return;
        }

        if (activeAudio.clip != null)
        {
            var newClipName = string.Empty;
            if (setting.clip != null)
            {
                newClipName = setting.clip.name;
            }
            if (activeAudio.clip.name.Equals(newClipName))
            {
                // ignore, it's the same clip! Playing the same causes it to stop.
                return;
            }
        }

        if (activeAudio.clip == null)
        {
            audioClip = activeAudio;
            transClip = transitioningAudio;
        }
        else if (transitioningAudio.clip == null)
        {
            audioClip = transitioningAudio;
            transClip = activeAudio;
        }
        else
        {
            // both are busy!
            audioClip = transitioningAudio;
            transClip = activeAudio;
        }

        if (setting.clip != null)
        {
            audioClip.clip = setting.clip;
            audioClip.pitch = setting.pitch;
        }

        audioClip.loop = SongShouldLoop(setting);

        AudioClip clipToPlay = null;

        switch (setting.audLocation)
        {
            case MasterAudio.AudioLocation.Clip:
                if (setting.clip == null)
                {
                    MasterAudio.LogWarning("MasterAudio will not play empty Playlist clip for PlaylistController '" + this.transform.name + "'.");
                    return;
                }

                clipToPlay = setting.clip;
                break;
            case MasterAudio.AudioLocation.ResourceFile:
                clipToPlay = AudioResourceOptimizer.PopulateResourceSongToPlaylistController(setting.resourceFileName, this.currentPlaylist.playlistName);
                if (clipToPlay == null)
                {
                    return;
                }
                break;
        }

        audioClip.clip = clipToPlay;
        audioClip.pitch = setting.pitch;

        // set last known time for current song.
        if (currentSong != null)
        {
            currentSong.lastKnownTimePoint = activeAudio.timeSamples;
        }

        if (CrossFadeTime == 0 || transClip.clip == null)
        {
            CeaseAudioSource(transClip);
            audioClip.volume = setting.volume * PlaylistVolume;

            if (!ActiveAudioSource.isPlaying && currentPlaylist != null && currentPlaylist.fadeInFirstSong)
            {
                CrossFadeNow(audioClip);
            }
        }
        else
        {
            CrossFadeNow(audioClip);
        }

        SetDuckProperties();

        audioClip.Play(); // need to play before setting time or it sometimes resets back to zero.
        songsPlayedFromPlaylist++;

        var songTimeChanged = false;

        if (syncGroupNum > 0)
        {
            var firstMatchingGroupController = PlaylistController.Instances.Find(delegate(PlaylistController obj)
            {
                return obj != this && obj.syncGroupNum == syncGroupNum && obj.ActiveAudioSource.isPlaying;
            });

            if (firstMatchingGroupController != null)
            {
                audioClip.timeSamples = firstMatchingGroupController.activeAudio.timeSamples;
                songTimeChanged = true;
            }
        }

        // this code will adjust the starting position of a song, but shouldn't do so when you first change Playlists.
        if (currentPlaylist != null) {
            if (songsPlayedFromPlaylist <= 1) {
                audioClip.timeSamples = 0; // reset pointer so a new Playlist always starts at the beginning.
            } else {
                switch (currentPlaylist.songTransitionType) {
                    case MasterAudio.SongFadeInPosition.SynchronizeClips:
                        if (!songTimeChanged) { // otherwise the sync group code above will get defeated.
                            transitioningAudio.timeSamples = activeAudio.timeSamples;
                        }
                        break;
                    case MasterAudio.SongFadeInPosition.NewClipFromLastKnownPosition:
                        var thisSongInPlaylist = currentPlaylist.MusicSettings.Find(delegate(MusicSetting obj)
                        {
                            return obj == setting;
                        });

                        if (thisSongInPlaylist != null)
                        {
                            transitioningAudio.timeSamples = thisSongInPlaylist.lastKnownTimePoint;
                        }
                        break;
                }
            }
        }

        if (SongChanged != null)
        {
            var clipName = String.Empty;
            if (audioClip != null)
            {
                clipName = audioClip.clip.name;
            }
            SongChanged(clipName);
        }

        activeAudio = audioClip;
        transitioningAudio = transClip;

        activeAudioEndVolume = setting.volume * PlaylistVolume;
        var transStartVol = transitioningAudio.volume;
        if (currentSong != null)
        {
            transStartVol = currentSong.volume;
        }

        transitioningAudioStartVolume = transStartVol * PlaylistVolume;
        currentSong = setting;
    }
    public override void OnInspectorGUI() {
        EditorGUI.indentLevel = 0;

        _sounds = (MasterAudio)target;

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

        ScanGroups();

        if (!_isValid) {
            return;
        }

        if (_sounds.transform.parent != null) {
            DTGUIHelper.ShowRedError("You have the Master Audio game object as a child of another game object.");
            DTGUIHelper.ShowRedError("This is not a supported scenario and some things might break. Please unparent it.");
        }

        DTGUIHelper.HelpHeader("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/MasterAudioGO.htm");

        _isDirty = false;
        _previewer = _sounds.gameObject;

        var sliderIndicatorChars = 6;
        var sliderWidth = 40;

        if (MasterAudio.UseDbScaleForVolume) {
            sliderIndicatorChars = 9;
            sliderWidth = 56;
        }

        var fakeDirty = false;
        var allowPreview = !DTGUIHelper.IsPrefabInProjectView(_sounds);

        _playlistNames = new List<string>();

        var maxPlaylistNameChars = 11;
        foreach (var t in _sounds.musicPlaylists) {
            var pList = t;

            _playlistNames.Add(pList.playlistName);
            if (pList.playlistName.Length > maxPlaylistNameChars) {
                maxPlaylistNameChars = pList.playlistName.Length;
            }
        }

        var groupNameList = GroupNameList;

        var busFilterList = new List<string> { MasterAudio.AllBusesName, MasterAudioGroup.NoBus };

        var maxChars = 9;
        var busList = new List<string> { MasterAudioGroup.NoBus, NewBusName };

        var busVoiceLimitList = new List<string> { MasterAudio.NoVoiceLimitName };

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

        foreach (var t in _sounds.groupBuses) {
            var bus = t;
            busList.Add(bus.busName);
            busFilterList.Add(bus.busName);

            if (bus.busName.Length > maxChars) {
                maxChars = bus.busName.Length;
            }
        }
        var busListWidth = 9 * maxChars;
        var playlistListWidth = 9 * maxPlaylistNameChars;
        var extraPlaylistLength = 0;
        if (maxPlaylistNameChars > 11) {
            extraPlaylistLength = 9 * (11 - maxPlaylistNameChars);
        }

        PlaylistController.Instances = null;
        var pcs = PlaylistController.Instances;
        var plControllerInScene = pcs.Count > 0;

        var labelWidth = 163;
        if (!MasterAudio.UseDbScaleForVolume) {
            labelWidth = 138;
        }

        if (!Application.isPlaying) {
            MasterAudio.ListenerTrans = null; // prevent caching
            _sounds.UpdateLocation();
        }

        // mixer master volume!
        EditorGUILayout.BeginHorizontal();
        var volumeBefore = _sounds._masterAudioVolume;
        GUILayout.Label(DTGUIHelper.LabelVolumeField("Master Mixer Volume"), GUILayout.Width(labelWidth));

        GUILayout.Space(5);

        var topSliderWidth = _sounds.MixerWidth;
        if (topSliderWidth == MasterAudio.MixerWidthMode.Wide) {
            topSliderWidth = MasterAudio.MixerWidthMode.Normal;
        }

        var newMasterVol = DTGUIHelper.DisplayVolumeField(_sounds._masterAudioVolume, DTGUIHelper.VolumeFieldType.GlobalVolume, topSliderWidth);
        if (newMasterVol != _sounds._masterAudioVolume) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Master Mixer Volume");
            if (Application.isPlaying) {
                MasterAudio.MasterVolumeLevel = newMasterVol;
            } else {
                _sounds._masterAudioVolume = newMasterVol;
            }
        }

        var mixerMuteButtonPressed = DTGUIHelper.AddMixerMuteButton("Mixer", _sounds);
        GUILayout.FlexibleSpace();

        if (mixerMuteButtonPressed == DTGUIHelper.DTFunctionButtons.Mute) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Mixer Mute");

            _sounds.mixerMuted = !_sounds.mixerMuted;
            if (Application.isPlaying) {
                MasterAudio.MixerMuted = _sounds.mixerMuted;
            } else {
                foreach (var aGroup in groups) {
                    aGroup.isMuted = _sounds.mixerMuted;
                    if (aGroup.isMuted) {
                        aGroup.isSoloed = false;
                    }
                }
            }
        }

        EditorGUILayout.EndHorizontal();

        if (volumeBefore != _sounds._masterAudioVolume) {
            // fix it for realtime adjustments!
            MasterAudio.MasterVolumeLevel = _sounds._masterAudioVolume;
        }

        // playlist master volume!
        if (plControllerInScene) {
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label(DTGUIHelper.LabelVolumeField("Master Playlist Volume"), GUILayout.Width(labelWidth));
            GUILayout.Space(5);
            var newPlaylistVol = DTGUIHelper.DisplayVolumeField(_sounds._masterPlaylistVolume, DTGUIHelper.VolumeFieldType.GlobalVolume, topSliderWidth);
            if (newPlaylistVol != _sounds._masterPlaylistVolume) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Master Playlist Volume");
                if (Application.isPlaying) {
                    MasterAudio.PlaylistMasterVolume = newPlaylistVol;
                } else {
                    _sounds._masterPlaylistVolume = newPlaylistVol;
                }
            }

            var playlistMuteButtonPressed = DTGUIHelper.AddPlaylistMuteButton("All Playlists", _sounds);
            if (playlistMuteButtonPressed == DTGUIHelper.DTFunctionButtons.Mute) {
                if (Application.isPlaying) {
                    MasterAudio.PlaylistsMuted = !MasterAudio.PlaylistsMuted;
                } else {
                    _sounds.playlistsMuted = !_sounds.playlistsMuted;

                    foreach (var t in pcs) {
                        if (_sounds.playlistsMuted) {
                            t.MutePlaylist();
                        } else {
                            t.UnmutePlaylist();
                        }

                        EditorUtility.SetDirty(t);
                    }
                }
            }

            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Master Crossfade Time", GUILayout.Width(labelWidth));

            GUILayout.Space(5);
            var width = topSliderWidth == MasterAudio.MixerWidthMode.Narrow ? 61 : 198;
            var newCrossTime = GUILayout.HorizontalSlider(_sounds.crossFadeTime, 0f, MasterAudio.MaxCrossFadeTimeSeconds, GUILayout.Width(width));
            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (newCrossTime != _sounds.crossFadeTime) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Master Crossfade Time");
                _sounds.crossFadeTime = newCrossTime;
            }

            var newCross = EditorGUILayout.FloatField(_sounds.crossFadeTime, GUILayout.Width(50));
            if (newCross != _sounds.crossFadeTime) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Master Crossfade Time");
                if (newCross < 0) {
                    newCross = 0;
                } else if (newCross > 10) {
                    newCross = 10;
                }
                _sounds.crossFadeTime = newCross;
            }

            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            // jukebox controls
            if (Application.isPlaying) {
                DisplayJukebox();
            }
        } else {
            DTGUIHelper.VerticalSpace(2);
        }

        // Localization section Start
        EditorGUI.indentLevel = 0;

        var state = _sounds.showLocalization;
        var text = "Languages";

        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
        if (!state) {
            GUI.backgroundColor = DTGUIHelper.InactiveHeaderColor;
        } else {
            GUI.backgroundColor = DTGUIHelper.ActiveHeaderColor;
        }

        GUILayout.BeginHorizontal();

#if UNITY_3_5_7
        if (!state) {
            text += " (Click to expand)";
        }
#else
        text = "<b><size=11>" + text + "</size></b>";
#endif
        if (state) {
            text = "\u25BC " + text;
        } else {
            text = "\u25BA " + text;
        }
        if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) {
            state = !state;
        }

        GUILayout.Space(2f);

        if (state != _sounds.showLocalization) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Languages");
            _sounds.showLocalization = state;
        }

        DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/Localization.htm");

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

        if (_sounds.showLocalization) {
            DTGUIHelper.BeginGroupedControls();
            if (Application.isPlaying) {
                DTGUIHelper.ShowColorWarning("Language settings cannot be changed during runtime");
            } else {
                int? langToRemove = null;
                int? langToAdd = null;

                for (var i = 0; i < _sounds.supportedLanguages.Count; i++) {
                    var aLang = _sounds.supportedLanguages[i];

                    DTGUIHelper.StartGroupHeader();
                    EditorGUILayout.BeginHorizontal();

                    EditorGUILayout.LabelField("Supported Lang. " + (i + 1), GUILayout.Width(120));
                    var newLang = (SystemLanguage)EditorGUILayout.EnumPopup("", aLang, GUILayout.Width(130));
                    if (newLang != aLang) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Supported Language");
                        _sounds.supportedLanguages[i] = newLang;
                    }
                    GUILayout.FlexibleSpace();

                    var buttonPressed = DTGUIHelper.AddFoldOutListItemButtonItems(i, _sounds.supportedLanguages.Count, "Supported Language", true);

                    switch (buttonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            langToRemove = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Add:
                            langToAdd = i;
                            break;
                    }

                    EditorGUILayout.EndHorizontal();
                    DTGUIHelper.EndGroupHeader();
                    DTGUIHelper.AddSpaceForNonU5(2);
                }

                if (langToAdd.HasValue) {
                    _sounds.supportedLanguages.Insert(langToAdd.Value + 1, SystemLanguage.Unknown);
                } else if (langToRemove.HasValue) {
                    if (_sounds.supportedLanguages.Count <= 1) {
                        DTGUIHelper.ShowAlert("You cannot delete the last Supported Language, although you do not have to use Localization.");
                    } else {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "Delete Supported Language");
                        _sounds.supportedLanguages.RemoveAt(langToRemove.Value);
                    }
                }

                if (!_sounds.supportedLanguages.Contains(_sounds.defaultLanguage)) {
                    DTGUIHelper.ShowLargeBarAlert("Please add your default language under Supported Languages as well.");
                }

                var newLang2 = (SystemLanguage)EditorGUILayout.EnumPopup(new GUIContent("Default Language", "This language will be used if the user's current language is not supported."), _sounds.defaultLanguage);
                if (newLang2 != _sounds.defaultLanguage) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Default Language");
                    _sounds.defaultLanguage = newLang2;
                }

                var newMode = (MasterAudio.LanguageMode)EditorGUILayout.EnumPopup("Language Mode", _sounds.langMode);
                if (newMode != _sounds.langMode) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Language Mode");
                    _sounds.langMode = newMode;
                    AudioResourceOptimizer.ClearSupportLanguageFolder();
                }

                if (_sounds.langMode == MasterAudio.LanguageMode.SpecificLanguage) {
                    var newLang = (SystemLanguage)EditorGUILayout.EnumPopup(new GUIContent("Use Specific Language", "This language will be used instead of your computer's setting. This is useful for testing other languages."), _sounds.testLanguage);
                    if (newLang != _sounds.testLanguage) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Use Specific");
                        _sounds.testLanguage = newLang;
                        AudioResourceOptimizer.ClearSupportLanguageFolder();
                    }

                    if (_sounds.supportedLanguages.Contains(_sounds.testLanguage)) {
                        DTGUIHelper.ShowLargeBarAlert("Please select your Specific Language under Supported Languages as well.");
                        DTGUIHelper.ShowLargeBarAlert("If you do not, it will use your Default Language instead.");
                    }
                } else if (_sounds.langMode == MasterAudio.LanguageMode.DynamicallySet) {
                    DTGUIHelper.ShowLargeBarAlert("Dynamic Language currently set to: " + MasterAudio.DynamicLanguage.ToString());
                }
            }
            DTGUIHelper.EndGroupedControls();
        }

        // Advanced section Start
        DTGUIHelper.VerticalSpace(3);

        EditorGUI.indentLevel = 0;

        state = _sounds.showAdvancedSettings;
        text = "Advanced Settings";

        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
        if (!state) {
            GUI.backgroundColor = DTGUIHelper.InactiveHeaderColor;
        } else {
            GUI.backgroundColor = DTGUIHelper.ActiveHeaderColor;
        }

        GUILayout.BeginHorizontal();

#if UNITY_3_5_7
        if (!state) {
            text += " (Click to expand)";
        }
#else
        text = "<b><size=11>" + text + "</size></b>";
#endif
        if (state) {
            text = "\u25BC " + text;
        } else {
            text = "\u25BA " + text;
        }
        if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) {
            state = !state;
        }

        GUILayout.Space(2f);

        if (state != _sounds.showAdvancedSettings) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Advanced Settings");
            _sounds.showAdvancedSettings = state;
        }

        DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/AdvancedSettings.htm");

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

        if (_sounds.showAdvancedSettings) {
            DTGUIHelper.BeginGroupedControls();
            if (!Application.isPlaying) {
                var newPersist = EditorGUILayout.Toggle(new GUIContent("Persist Across Scenes", "Turn this on only if you need music or other sounds to play across Scene changes. If not, create a different Master Audio prefab in each Scene."), _sounds.persistBetweenScenes);
                if (newPersist != _sounds.persistBetweenScenes) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Persist Across Scenes");
                    _sounds.persistBetweenScenes = newPersist;
                }
            }

            if (_sounds.persistBetweenScenes && plControllerInScene) {
                DTGUIHelper.ShowColorWarning("Playlist Controller(s) will also persist between scenes!");
            }

#if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
            // no support
#else
            var newGap = EditorGUILayout.Toggle(new GUIContent("Gapless Music Switching", "Turn this option on if you need perfect gapless transitions between clips in your Playlists. For Resource Files, this will take more audio memory as 2 clips are generally loaded into memory at the same time, so only use it if you need to."), _sounds.useGaplessPlaylists);
            if (newGap != _sounds.useGaplessPlaylists) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Gapless Music Switching");
                _sounds.useGaplessPlaylists = newGap;
            }
#endif

            var newFollow = EditorGUILayout.Toggle(new GUIContent("Follow Audio Listener", "This option will make previewing sounds in both Edit and Play mode always audible because the Audio Sources in this game object will be at the same location as the Audio Listener."), _sounds.followAudioListener);
            if (newFollow != _sounds.followAudioListener) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Follow Audio Listener");
                _sounds.followAudioListener = newFollow;
            }

            var newSave = EditorGUILayout.Toggle(new GUIContent("Save Runtime Changes", "Turn this on if you want to do real time adjustments to the mix, Master Audio prefab, Groups and Playlist Controllers and have the changes stick after you stop playing."), _sounds.saveRuntimeChanges);
            if (newSave != _sounds.saveRuntimeChanges) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Save Runtime Changes");
                _sounds.saveRuntimeChanges = newSave;
                _persistChanges = newSave;
            }

            var newIgnore = EditorGUILayout.Toggle(new GUIContent("Ignore Time Scale", "Turn this option on only if you need to use EventSounds Start event at zero timescale or DelayBetweenSongs"), _sounds.ignoreTimeScale);
            if (newIgnore != _sounds.ignoreTimeScale) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Ignore Time Scale");
                _sounds.ignoreTimeScale = newIgnore;
            }

            DTGUIHelper.StartGroupHeader();
            EditorGUILayout.BeginHorizontal();
            var newAutoPrioritize = GUILayout.Toggle(_sounds.prioritizeOnDistance, new GUIContent(" Apply Distance Priority", "Turn this on to have Master Audio automatically assign Priority to all audio, based on distance from the Audio Listener. Playlist Controller and 2D sounds are unaffected."));
            if (newAutoPrioritize != _sounds.prioritizeOnDistance) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Prioritize By Distance");
                _sounds.prioritizeOnDistance = newAutoPrioritize;
            }

            DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/AdvancedSettings.htm#DistancePriority");
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();

            if (_sounds.prioritizeOnDistance) {
                EditorGUI.indentLevel = 0;

                var reevalIndex = _sounds.rePrioritizeEverySecIndex;

                var evalTimes = new List<string>();
                foreach (var t in _reevaluatePriorityTimes) {
                    evalTimes.Add(t + " seconds");
                }

                var newRepri = EditorGUILayout.Popup("Reprioritize Time Gap", reevalIndex, evalTimes.ToArray());
                if (newRepri != reevalIndex) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Re-evaluate time");
                    _sounds.rePrioritizeEverySecIndex = newRepri;
                }

                var newContinual = EditorGUILayout.Toggle("Use Clip Age Priority", _sounds.useClipAgePriority);
                if (newContinual != _sounds.useClipAgePriority) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Use Clip Age Priority");
                    _sounds.useClipAgePriority = newContinual;
                }
            }
            EditorGUILayout.EndVertical();

            EditorGUI.indentLevel = 1;

            DTGUIHelper.AddSpaceForNonU5(2);

            DTGUIHelper.StartGroupHeader();

            EditorGUILayout.BeginHorizontal();
            var newVisual = DTGUIHelper.Foldout(_sounds.visualAdvancedExpanded, "Visual Settings");
            if (newVisual != _sounds.visualAdvancedExpanded) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Visual Settings");
                _sounds.visualAdvancedExpanded = newVisual;
            }
            DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/AdvancedSettings.htm#VisualSettings");
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();

            if (_sounds.visualAdvancedExpanded) {
                EditorGUI.indentLevel = 0;

                var newGiz = EditorGUILayout.Toggle(new GUIContent("Show Variation Gizmos", "Turning this option on will show you where your Variation and Event Sounds components are in the Scene with an 'M' icon."), _sounds.showGizmos);
                if (newGiz != _sounds.showGizmos) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Show Variation Gizmos");
                    _sounds.showGizmos = newGiz;
                }

                var newWidth = (MasterAudio.MixerWidthMode)EditorGUILayout.EnumPopup("Inspector Width", _sounds.MixerWidth);
                if (newWidth != _sounds.MixerWidth) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Inspector Width");
                    _sounds.MixerWidth = newWidth;
                }

                if (_sounds.MixerWidth == MasterAudio.MixerWidthMode.Narrow) {
                    var showBus = EditorGUILayout.Toggle("Show Buses in Narrow", _sounds.busesShownInNarrow);
                    if (showBus != _sounds.busesShownInNarrow) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Show Buses in Narrow");
                        _sounds.busesShownInNarrow = showBus;
                    }
                }
            }
            EditorGUILayout.EndVertical();

            EditorGUI.indentLevel = 1;
            DTGUIHelper.AddSpaceForNonU5(2);
            DTGUIHelper.StartGroupHeader();
            EditorGUILayout.BeginHorizontal();
            var exp = DTGUIHelper.Foldout(_sounds.showFadingSettings, "Fading Settings");
            if (exp != _sounds.showFadingSettings) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Fading Settings");
                _sounds.showFadingSettings = exp;
            }
            DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/AdvancedSettings.htm#FadingSettings");
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();
            if (_sounds.showFadingSettings) {
                EditorGUI.indentLevel = 0;
                DTGUIHelper.ShowLargeBarAlert("Fading to zero volume on the following causes their audio to stop (if checked).");

                var newStop = EditorGUILayout.Toggle("Buses", _sounds.stopZeroVolumeBuses);
                if (newStop != _sounds.stopZeroVolumeBuses) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Buses Stop");
                    _sounds.stopZeroVolumeBuses = newStop;
                }

                newStop = EditorGUILayout.Toggle("Variations", _sounds.stopZeroVolumeVariations);
                if (newStop != _sounds.stopZeroVolumeVariations) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Variations Stop");
                    _sounds.stopZeroVolumeVariations = newStop;
                }

                newStop = EditorGUILayout.Toggle("Sound Groups", _sounds.stopZeroVolumeGroups);
                if (newStop != _sounds.stopZeroVolumeGroups) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Sound Groups Stop");
                    _sounds.stopZeroVolumeGroups = newStop;
                }

                newStop = EditorGUILayout.Toggle(new GUIContent("Playlist Controllers", "Automatic crossfading will not trigger stop."), _sounds.stopZeroVolumePlaylists);
                if (newStop != _sounds.stopZeroVolumePlaylists) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Playlist Controllers Stop");
                    _sounds.stopZeroVolumePlaylists = newStop;
                }
            }
            EditorGUILayout.EndVertical();

            EditorGUI.indentLevel = 1;
            DTGUIHelper.AddSpaceForNonU5(2);
            DTGUIHelper.StartGroupHeader();

            EditorGUILayout.BeginHorizontal();
            var newResource = DTGUIHelper.Foldout(_sounds.resourceAdvancedExpanded, "Resource File Settings");
            if (newResource != _sounds.resourceAdvancedExpanded) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Resource File Settings");
                _sounds.resourceAdvancedExpanded = newResource;
            }
            DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/AdvancedSettings.htm#ResourceSettings");
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.EndVertical();

            if (_sounds.resourceAdvancedExpanded) {
                EditorGUI.indentLevel = 0;
                if (MasterAudio.HasAsyncResourceLoaderFeature()) {
                    var newAsync = EditorGUILayout.Toggle(new GUIContent("Always Load Res. Async", "Checking this means that you will not have this control per Sound Group or Playlist. All Resource files will be loaded asynchronously."), _sounds.resourceClipsAllLoadAsync);
                    if (newAsync != _sounds.resourceClipsAllLoadAsync) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Always Load Resources Async");
                        _sounds.resourceClipsAllLoadAsync = newAsync;
                    }
                }

                var newResourcePause = EditorGUILayout.Toggle(new GUIContent("Keep Paused Resources", "If you check this box, Resource files will not be automatically unloaded from memory when you pause them. Use at your own risk!"), _sounds.resourceClipsPauseDoNotUnload);
                if (newResourcePause != _sounds.resourceClipsPauseDoNotUnload) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Keep Paused Resources");
                    _sounds.resourceClipsPauseDoNotUnload = newResourcePause;
                }
            }
            EditorGUILayout.EndVertical();

            EditorGUI.indentLevel = 1;
            DTGUIHelper.AddSpaceForNonU5(2);
            DTGUIHelper.StartGroupHeader();
            EditorGUILayout.BeginHorizontal();
            var newLog = DTGUIHelper.Foldout(_sounds.logAdvancedExpanded, "Logging Settings");
            if (newLog != _sounds.logAdvancedExpanded) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Logging Settings");
                _sounds.logAdvancedExpanded = newLog;
            }
            DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/AdvancedSettings.htm#LoggingSettings");
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.EndVertical();

            if (_sounds.logAdvancedExpanded) {
                EditorGUI.indentLevel = 0;
                newLog = EditorGUILayout.Toggle("Disable Logging", _sounds.disableLogging);
                if (newLog != _sounds.disableLogging) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Disable Logging");
                    _sounds.disableLogging = newLog;
                }

                if (!_sounds.disableLogging) {
                    newLog = EditorGUILayout.Toggle("Log Sounds", _sounds.LogSounds);
                    if (newLog != _sounds.LogSounds) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Log Sounds");
                        if (Application.isPlaying) {
                            MasterAudio.LogSoundsEnabled = _sounds.LogSounds;
                        }
                        _sounds.LogSounds = newLog;
                    }

                    newLog = EditorGUILayout.Toggle("Log Custom Events", _sounds.logCustomEvents);
                    if (newLog != _sounds.logCustomEvents) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Log Custom Events");
                        _sounds.logCustomEvents = newLog;
                    }
                } else {
                    DTGUIHelper.ShowLargeBarAlert("Logging is disabled.");
                }
            }
            EditorGUILayout.EndVertical();

            DTGUIHelper.EndGroupedControls();
        }

        DTGUIHelper.ResetColors();
        // Music Ducking Start

        DTGUIHelper.VerticalSpace(3);

        EditorGUI.indentLevel = 0;

        state = _sounds.showMusicDucking;
        text = "Music Ducking";

        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
        if (!state) {
            GUI.backgroundColor = DTGUIHelper.InactiveHeaderColor;
        } else {
            GUI.backgroundColor = DTGUIHelper.ActiveHeaderColor;
        }

        GUILayout.BeginHorizontal();

#if UNITY_3_5_7
        if (!state) {
            text += " (Click to expand)";
        }
#else
        text = "<b><size=11>" + text + "</size></b>";
#endif
        if (state) {
            text = "\u25BC " + text;
        } else {
            text = "\u25BA " + text;
        }
        if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) {
            state = !state;
        }

        GUILayout.Space(2f);

        if (state != _sounds.showMusicDucking) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Show Music Ducking");
            _sounds.showMusicDucking = state;
        }

        DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/MusicDucking.htm");

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

        if (_sounds.showMusicDucking) {
            DTGUIHelper.BeginGroupedControls();
            var newEnableDuck = EditorGUILayout.BeginToggleGroup("Enable Ducking", _sounds.EnableMusicDucking);
            if (newEnableDuck != _sounds.EnableMusicDucking) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Enable Ducking");
                _sounds.EnableMusicDucking = newEnableDuck;
            }

            EditorGUILayout.Separator();

            var newMult = EditorGUILayout.Slider("Default Ducked Vol Cut", _sounds.defaultDuckedVolumeCut, DTGUIHelper.MinDb, DTGUIHelper.MaxDb);
            if (newMult != _sounds.defaultDuckedVolumeCut) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Default Ducked Vol Cut");
                _sounds.defaultDuckedVolumeCut = newMult;
            }

            var newDefault = EditorGUILayout.Slider("Default Unduck Time", _sounds.defaultUnduckTime, 0f, 5f);
            if (newDefault != _sounds.defaultUnduckTime) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Default Unduck Time");
                _sounds.defaultUnduckTime = newDefault;
            }

			newDefault = EditorGUILayout.Slider("Default Begin Unduck", _sounds.defaultRiseVolStart, 0f, 1f);
			if (newDefault != _sounds.defaultRiseVolStart) {
				AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Default Begin Unduck");
				_sounds.defaultRiseVolStart = newDefault;
			}

            GUI.contentColor = DTGUIHelper.BrightButtonColor;
            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(10);

            if (GUILayout.Button(new GUIContent("Add Duck Group"), EditorStyles.toolbarButton, GUILayout.Width(100))) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "Add Duck Group");
                _sounds.musicDuckingSounds.Add(new DuckGroupInfo() {
                    soundType = MasterAudio.NoGroupName,
                    riseVolStart = _sounds.defaultRiseVolStart,
                    duckedVolumeCut = _sounds.defaultDuckedVolumeCut,
                    unduckTime = _sounds.defaultUnduckTime
                });
            }

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

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

                var spacerWidth = _sounds.MixerWidth == MasterAudio.MixerWidthMode.Wide ? 60 : 0;

                if (_sounds.musicDuckingSounds.Count > 0) {
                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Label("Sound Group", EditorStyles.boldLabel);
                    GUILayout.FlexibleSpace();
                    GUILayout.Label(new GUIContent("Vol. Cut (dB)", "Amount to duck the music volume."), EditorStyles.boldLabel);
                    GUILayout.Space(6 + spacerWidth);
                    GUILayout.Label(new GUIContent("Beg. Unduck", "Begin Unducking after this amount of the sound has been played."), EditorStyles.boldLabel);
                    GUILayout.Space(13 + spacerWidth);
                    GUILayout.Label(new GUIContent("Unduck Time", "Unducking will take X seconds."), EditorStyles.boldLabel);
                    GUILayout.Space(54 + spacerWidth);
                    EditorGUILayout.EndHorizontal();
                }

                var slidWidth = _sounds.MixerWidth == MasterAudio.MixerWidthMode.Wide ? 120 : 60;

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

                    DTGUIHelper.StartGroupHeader();

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

                    GUILayout.FlexibleSpace();

                    GUI.contentColor = DTGUIHelper.BrightButtonColor;
                    GUILayout.TextField(duckSound.duckedVolumeCut.ToString("N1"), 20, EditorStyles.miniLabel);

                    var newDuckMult = GUILayout.HorizontalSlider(duckSound.duckedVolumeCut, DTGUIHelper.MinDb, DTGUIHelper.MaxDb, GUILayout.Width(slidWidth));
                    if (newDuckMult != duckSound.duckedVolumeCut) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Ducked Vol Cut");
                        duckSound.duckedVolumeCut = newDuckMult;
                    }
                    GUI.contentColor = Color.white;

                    GUI.contentColor = DTGUIHelper.BrightButtonColor;
                    GUILayout.TextField(duckSound.riseVolStart.ToString("N2"), 20, EditorStyles.miniLabel);

                    var newUnduck = GUILayout.HorizontalSlider(duckSound.riseVolStart, 0f, 1f, GUILayout.Width(slidWidth));
                    if (newUnduck != duckSound.riseVolStart) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Begin Unduck");
                        duckSound.riseVolStart = newUnduck;
                    }
                    GUI.contentColor = Color.white;

                    GUILayout.Space(4);
                    GUILayout.TextField(duckSound.unduckTime.ToString("N2"), 20, EditorStyles.miniLabel);
                    var newTime = GUILayout.HorizontalSlider(duckSound.unduckTime, 0f, 5f, GUILayout.Width(slidWidth));
                    if (newTime != duckSound.unduckTime) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Unduck Time");
                        duckSound.unduckTime = newTime;
                    }

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

                    EditorGUILayout.EndHorizontal();
                    DTGUIHelper.EndGroupHeader();
                    DTGUIHelper.AddSpaceForNonU5(2);
                }

                if (duckSoundToRemove.HasValue) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "delete Duck Group");
                    _sounds.musicDuckingSounds.RemoveAt(duckSoundToRemove.Value);
                }

            }
            EditorGUILayout.EndToggleGroup();

            DTGUIHelper.EndGroupedControls();
        }
        // Music Ducking End

        DTGUIHelper.ResetColors();
        // Sound Groups Start		
        EditorGUI.indentLevel = 0;  // Space will handle this for the header
        DTGUIHelper.VerticalSpace(3);

        state = _sounds.areGroupsExpanded;
        text = "Group Mixer";

        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
        if (!state) {
            GUI.backgroundColor = DTGUIHelper.InactiveHeaderColor;
        } else {
            GUI.backgroundColor = DTGUIHelper.ActiveHeaderColor;
        }

        GUILayout.BeginHorizontal();

#if UNITY_3_5_7
        if (!state) {
            text += " (Click to expand)";
        }
#else
        text = "<b><size=11>" + text + "</size></b>";
#endif
        if (state) {
            text = "\u25BC " + text;
        } else {
            text = "\u25BA " + text;
        }
        if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) {
            state = !state;
        }

        GUILayout.Space(2f);

        if (state != _sounds.areGroupsExpanded) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Group Mixer");
            _sounds.areGroupsExpanded = state;
        }

        GUI.color = Color.white;
        DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/GroupMixer.htm");

        EditorGUILayout.EndHorizontal();

        GameObject groupToDelete = null;
        // ReSharper disable once TooWideLocalVariableScope
        // ReSharper disable once RedundantAssignment
        var audSrcTemplateIndex = -1;
        var applyTemplateToAll = false;

        if (_sounds.areGroupsExpanded) {
            DTGUIHelper.BeginGroupedControls();

            EditorGUI.indentLevel = 1;

            DTGUIHelper.StartGroupHeader();
            EditorGUILayout.BeginHorizontal();

            var newShow = DTGUIHelper.Foldout(_sounds.showGroupCreation, "Group Creation");
            if (newShow != _sounds.showGroupCreation) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Group Creation");
                _sounds.showGroupCreation = !_sounds.showGroupCreation;
            }
            DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/GroupMixer.htm#GroupCreation");
            EditorGUILayout.EndHorizontal();

            GUI.contentColor = Color.white;
            EditorGUILayout.EndVertical();

            if (_sounds.showGroupCreation) {
                EditorGUI.indentLevel = 0;
                var groupTemplateIndex = -1;

                if (_sounds.audioSourceTemplates.Count > 0 && !Application.isPlaying && _sounds.showGroupCreation && _sounds.transform.childCount > 0) {
                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Space(10);
                    GUI.contentColor = DTGUIHelper.BrightButtonColor;
                    if (GUILayout.Button("Apply Audio Source Template to All", EditorStyles.toolbarButton, GUILayout.Width(190))) {
                        applyTemplateToAll = true;
                    }
                    GUI.contentColor = Color.white;
                    EditorGUILayout.EndHorizontal();
                }

                var newTemp = EditorGUILayout.Toggle("Use Group Templates", _sounds.useGroupTemplates);
                if (newTemp != _sounds.useGroupTemplates) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Use Group Templates");
                    _sounds.useGroupTemplates = newTemp;
                }

                if (_sounds.useGroupTemplates) {
                    _groupTemplateNames = new List<string>();

                    foreach (var temp in _sounds.groupTemplates) {
                        if (temp == null) {
                            continue;
                        }
                        _groupTemplateNames.Add(temp.name);
                    }

                    var templatesMissing = false;

                    if (Directory.Exists(MasterAudio.GroupTemplateFolder)) {
                        var grpTemplates = Directory.GetFiles(MasterAudio.GroupTemplateFolder, "*.prefab").Length;
                        if (grpTemplates > _sounds.groupTemplates.Count) {
                            templatesMissing = true;
                            DTGUIHelper.ShowLargeBarAlert("There are " + (grpTemplates - _sounds.groupTemplates.Count) + " Group Template(s) that aren't set up in this MA prefab. Locate them in Plugins/DarkTonic/MasterAudio/Sources/Prefabs/GroupTemplates and drag them in below.");
                        }
                    }

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

                        GUI.color = DTGUIHelper.DragAreaColor;

                        var dragArea = GUILayoutUtility.GetRect(0f, 35f, GUILayout.ExpandWidth(true));
                        GUI.Box(dragArea, "Drag prefabs here from Project View to create Group Templates!");

                        GUI.color = Color.white;

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

                                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

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

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

                                        AddGroupTemplate(temp);
                                    }
                                }
                                Event.current.Use();
                                break;
                        }
                        EditorGUILayout.EndVertical();
                        // create groups end
                    }

                    if (_groupTemplateNames.Count == 0) {
                        DTGUIHelper.ShowRedError("You cannot create Groups without Templates. Drag them in or disable Group Templates.");
                    } else {
                        groupTemplateIndex = _groupTemplateNames.IndexOf(_sounds.groupTemplateName);
                        if (groupTemplateIndex < 0) {
                            groupTemplateIndex = 0;
                            _sounds.groupTemplateName = _groupTemplateNames[0];
                        }

                        var newIndex = EditorGUILayout.Popup("Group Template", groupTemplateIndex, _groupTemplateNames.ToArray());
                        if (newIndex != groupTemplateIndex) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Group Template");
                            _sounds.groupTemplateName = _groupTemplateNames[newIndex];
                        }
                    }
                }

                _audioSourceTemplateNames = new List<string>();

                foreach (var temp in _sounds.audioSourceTemplates) {
                    if (temp == null) {
                        continue;
                    }
                    _audioSourceTemplateNames.Add(temp.name);
                }

                var audTemplatesMissing = false;

                if (Directory.Exists(MasterAudio.AudioSourceTemplateFolder)) {
                    var audioSrcTemplates = Directory.GetFiles(MasterAudio.AudioSourceTemplateFolder, "*.prefab").Length;
                    if (audioSrcTemplates > _sounds.audioSourceTemplates.Count) {
                        audTemplatesMissing = true;
                        DTGUIHelper.ShowLargeBarAlert("There are " + (audioSrcTemplates - _sounds.audioSourceTemplates.Count) + " Audio Source Template(s) that aren't set up in this MA prefab. Locate them in Plugins/DarkTonic/MasterAudio/Sources/Prefabs/AudioSourceTemplates and drag them in below.");
                    }
                }

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

                    GUI.color = DTGUIHelper.DragAreaColor;

                    var dragArea = GUILayoutUtility.GetRect(0f, 35f, GUILayout.ExpandWidth(true));
                    GUI.Box(dragArea, "Drag prefabs here from Project View to create Audio Source Templates!");

                    GUI.color = Color.white;

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

                            DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

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

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

                                    AddAudioSourceTemplate(temp);
                                }
                            }
                            Event.current.Use();
                            break;
                    }
                    EditorGUILayout.EndVertical();
                    // create groups end
                }

                if (_audioSourceTemplateNames.Count == 0) {
                    DTGUIHelper.ShowRedError("You have no Audio Source Templates. Drag them in to create them.");
                } else {
                    audSrcTemplateIndex = _audioSourceTemplateNames.IndexOf(_sounds.audioSourceTemplateName);
                    if (audSrcTemplateIndex < 0) {
                        audSrcTemplateIndex = 0;
                        _sounds.audioSourceTemplateName = _audioSourceTemplateNames[0];
                    }

                    var newIndex = EditorGUILayout.Popup("Audio Source Template", audSrcTemplateIndex, _audioSourceTemplateNames.ToArray());
                    if (newIndex != audSrcTemplateIndex) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Audio Source Template");
                        _sounds.audioSourceTemplateName = _audioSourceTemplateNames[newIndex];
                    }
                }

                if (_sounds.useGroupTemplates) {
                    DTGUIHelper.ShowColorWarning("Bulk Creation Mode is ONE GROUP PER CLIP when using Group Templates.");
                } else {
                    var newGroupMode = (MasterAudio.DragGroupMode)EditorGUILayout.EnumPopup("Bulk Creation Mode", _sounds.curDragGroupMode);
                    if (newGroupMode != _sounds.curDragGroupMode) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Bulk Creation Mode");
                        _sounds.curDragGroupMode = newGroupMode;
                    }
                }

                var newBulkMode = DTGUIHelper.GetRestrictedAudioLocation("Variation Create Mode", _sounds.bulkLocationMode);
                if (newBulkMode != _sounds.bulkLocationMode) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Bulk Variation Mode");
                    _sounds.bulkLocationMode = newBulkMode;
                }

                if (_sounds.bulkLocationMode == MasterAudio.AudioLocation.ResourceFile) {
                    DTGUIHelper.ShowColorWarning("Resource mode: make sure to drag from Resource folders only.");
                }

                var cannotCreateGroups = _sounds.useGroupTemplates && _sounds.groupTemplates.Count == 0;
                MasterAudioGroup createdGroup = null;

                if (!cannotCreateGroups) {
                    // create groups start
                    var anEvent = Event.current;

                    var useGroupTemplate = _sounds.useGroupTemplates && groupTemplateIndex > -1;

                    if (!allowPreview) {
                        DTGUIHelper.ShowLargeBarAlert("You are in Project View and cannot create or navigate Groups.");
                        DTGUIHelper.ShowRedError("Create this prefab from Master Audio Manager window. Do not drag into Scene!");
                    } else {
                        GUI.color = DTGUIHelper.DragAreaColor;
                        EditorGUILayout.BeginVertical();
                        var dragArea = GUILayoutUtility.GetRect(0f, 35f, GUILayout.ExpandWidth(true));
                        GUI.Box(dragArea, "Drag Audio clips here to create Groups!");

                        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();

                                    Transform groupTrans = null;

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

                                        if (useGroupTemplate) {
                                            createdGroup = CreateSoundGroupFromTemplate(aClip, groupTemplateIndex);
                                            continue;
                                        }

                                        if (_sounds.curDragGroupMode == MasterAudio.DragGroupMode.OneGroupPerClip) {
                                            CreateSoundGroup(aClip);
                                        } else {
                                            if (groupTrans == null) { // one group with variations
                                                groupTrans = CreateSoundGroup(aClip);
                                            } else {
                                                CreateVariation(groupTrans, aClip);
                                                // create the variations
                                            }
                                        }
                                    }
                                }
                                Event.current.Use();
                                break;
                        }
                        EditorGUILayout.EndVertical();
                    }
                    // create groups end
                }

                if (createdGroup != null) {
                    MasterAudioGroupInspector.RescanChildren(createdGroup);
                }
            }
            EditorGUILayout.EndVertical();

            EditorGUI.indentLevel = 0;

            DTGUIHelper.AddSpaceForNonU5(2);
            DTGUIHelper.StartGroupHeader();
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Group Control");
            DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/GroupMixer.htm#GroupControl");
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.EndVertical();

            DTGUIHelper.ResetColors();

#if UNITY_5
            DTGUIHelper.StartGroupHeader(1, false);

            var newSpatialType = (MasterAudio.AllMixerSpatialBlendType)EditorGUILayout.EnumPopup("Group Spatial Blend Rule", _sounds.mixerSpatialBlendType);
            if (newSpatialType != _sounds.mixerSpatialBlendType) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Group Spatial Blend Rule");
                _sounds.mixerSpatialBlendType = newSpatialType;

                if (Application.isPlaying) {
                    _sounds.SetSpatialBlendForMixer();
                } else {
                    SetSpatialBlendForGroupsEdit();
                }
            }

            switch (_sounds.mixerSpatialBlendType) {
                case MasterAudio.AllMixerSpatialBlendType.ForceAllToCustom:
                    DTGUIHelper.ShowLargeBarAlert(SpatialBlendSliderText);
                    var newBlend = EditorGUILayout.Slider("Group Spatial Blend", _sounds.mixerSpatialBlend, 0f, 1f);
                    if (newBlend != _sounds.mixerSpatialBlend) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Group Spatial Blend");
                        _sounds.mixerSpatialBlend = newBlend;
                        if (Application.isPlaying) {
                            _sounds.SetSpatialBlendForMixer();
                        } else {
                            SetSpatialBlendForGroupsEdit();
                        }
                    }
                    break;
                case MasterAudio.AllMixerSpatialBlendType.AllowDifferentPerGroup:
                    DTGUIHelper.ShowLargeBarAlert("Go to each Group's settings to change Spatial Blend. Defaults below are for new Groups.");

                    var newDefType = (MasterAudio.ItemSpatialBlendType)EditorGUILayout.EnumPopup("Default Blend Type", _sounds.newGroupSpatialType);
                    if (newDefType != _sounds.newGroupSpatialType) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Default Blend Type");
                        _sounds.newGroupSpatialType = newDefType;
                    }

                    if (_sounds.newGroupSpatialType == MasterAudio.ItemSpatialBlendType.ForceToCustom) {
                        newBlend = EditorGUILayout.Slider("Default Spatial Blend", _sounds.newGroupSpatialBlend, 0f, 1f);
                        if (newBlend != _sounds.newGroupSpatialBlend) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Default  Spatial Blend");
                            _sounds.newGroupSpatialBlend = newBlend;
                        }
                    }
                    break;
            }
            EditorGUILayout.EndVertical();
            DTGUIHelper.ResetColors();
#endif

            EditorGUI.indentLevel = 0;
            var newBusFilterIndex = -1;
            var busFilterActive = false;

            if (_sounds.groupBuses.Count > 0) {
                busFilterActive = true;
                var oldBusFilter = busFilterList.IndexOf(_sounds.busFilter);
                if (oldBusFilter == -1) {
                    oldBusFilter = 0;
                }

                newBusFilterIndex = EditorGUILayout.Popup("Bus Filter", oldBusFilter, busFilterList.ToArray());

                var newBusFilter = busFilterList[newBusFilterIndex];

                if (_sounds.busFilter != newBusFilter) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Bus Filter");
                    _sounds.busFilter = newBusFilter;
                }
            }

            if (groups.Count > 0) {
                var newUseTextGroupFilter = EditorGUILayout.Toggle("Use Text Group Filter", _sounds.useTextGroupFilter);
                if (newUseTextGroupFilter != _sounds.useTextGroupFilter) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Use Text Group Filter");
                    _sounds.useTextGroupFilter = newUseTextGroupFilter;
                }

                if (_sounds.useTextGroupFilter) {
                    EditorGUI.indentLevel = 1;

                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Space(10);
                    GUILayout.Label("Text Group Filter", GUILayout.Width(140));
                    var newTextFilter = GUILayout.TextField(_sounds.textGroupFilter, GUILayout.Width(180));
                    if (newTextFilter != _sounds.textGroupFilter) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Text Group Filter");
                        _sounds.textGroupFilter = newTextFilter;
                    }
                    GUILayout.Space(10);
                    GUI.contentColor = DTGUIHelper.BrightButtonColor;
                    if (GUILayout.Button("Clear", EditorStyles.toolbarButton, GUILayout.Width(70))) {
                        _sounds.textGroupFilter = string.Empty;
                    }
                    GUI.contentColor = Color.white;
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.Separator();
                }

                if (Application.isPlaying) {
                    var newHide = EditorGUILayout.Toggle("Filter Out Inactive", _sounds.hideGroupsWithNoActiveVars);
                    if (newHide != _sounds.hideGroupsWithNoActiveVars) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Filter Out Inactive");
                        _sounds.hideGroupsWithNoActiveVars = newHide;
                    }
                }
            }

            EditorGUI.indentLevel = 0;
            var groupButtonPressed = DTGUIHelper.DTFunctionButtons.None;

            MasterAudioGroup aGroup = null;
            var filteredGroups = new List<MasterAudioGroup>();

            filteredGroups.AddRange(groups);

            if (busFilterActive && !string.IsNullOrEmpty(_sounds.busFilter)) {
                if (newBusFilterIndex == 0) {
                    // no filter
                } else if (newBusFilterIndex == 1) {
                    filteredGroups.RemoveAll(delegate(MasterAudioGroup obj) {
                        return obj.busIndex != 0;
                    });
                } else {
                    filteredGroups.RemoveAll(delegate(MasterAudioGroup obj) {
                        return obj.busIndex != newBusFilterIndex;
                    });
                }
            }

            if (_sounds.useTextGroupFilter) {
                if (!string.IsNullOrEmpty(_sounds.textGroupFilter)) {
                    filteredGroups.RemoveAll(delegate(MasterAudioGroup obj) {
                        return !obj.transform.name.ToLower().Contains(_sounds.textGroupFilter.ToLower());
                    });
                }
            }

            if (Application.isPlaying && _sounds.hideGroupsWithNoActiveVars) {
                filteredGroups.RemoveAll(delegate(MasterAudioGroup obj) {
                    return obj.ActiveVoices == 0;
                });
            }

            var totalVoiceCount = 0;

            var selectAll = false;
            var deselectAll = false;
            var applyAudioSourceTemplate = false;

            var bulkSelectedGrps = new List<MasterAudioGroup>(filteredGroups.Count);

            if (groups.Count == 0) {
                DTGUIHelper.ShowLargeBarAlert("You currently have zero Sound Groups.");
            } else {
                var groupsFiltered = groups.Count - filteredGroups.Count;
                if (groupsFiltered > 0) {
                    DTGUIHelper.ShowLargeBarAlert(string.Format("{0}/{1} Group(s) filtered out.", groupsFiltered, groups.Count));
                }

                var allFilteredOut = groupsFiltered == groups.Count;

                if (_sounds.groupBuses.Count > 0 && !allFilteredOut) {
                    var newGroupByBus = EditorGUILayout.Toggle("Group by Bus", _sounds.groupByBus);
                    if (newGroupByBus != _sounds.groupByBus) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Group by Bus");
                        _sounds.groupByBus = newGroupByBus;
                    }
                }

                if (filteredGroups.Count > 0) {
                    var newSelectGrp = EditorGUILayout.Toggle("Bulk Group Changes", _sounds.showGroupSelect);
                    if (newSelectGrp != _sounds.showGroupSelect) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Bulk Group Changes");
                        _sounds.showGroupSelect = newSelectGrp;
                    }

                    if (_sounds.showGroupSelect) {
                        GUI.contentColor = DTGUIHelper.BrightButtonColor;
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.Space(10);
                        if (GUILayout.Button("Select All", EditorStyles.toolbarButton, GUILayout.Width(80))) {
                            selectAll = true;
                        }
                        GUILayout.Space(10);
                        if (GUILayout.Button("Deselect All", EditorStyles.toolbarButton, GUILayout.Width(80))) {
                            deselectAll = true;
                        }

                        foreach (var t in filteredGroups) {
                            if (t.isSelected) {
                                bulkSelectedGrps.Add(t);
                            }
                        }

                        if (!Application.isPlaying && _audioSourceTemplateNames.Count > 0 && bulkSelectedGrps.Count > 0) {
                            GUILayout.Space(10);
                            GUI.contentColor = DTGUIHelper.BrightButtonColor;
                            if (GUILayout.Button("Apply Audio Source Template", EditorStyles.toolbarButton, GUILayout.Width(160))) {
                                applyAudioSourceTemplate = true;
                            }
                        }
                        EditorGUILayout.EndHorizontal();
                        GUI.contentColor = Color.white;

                        if (bulkSelectedGrps.Count > 0) {
                            DTGUIHelper.ShowLargeBarAlert("Bulk editing - adjustments to a selected mixer Group will affect all " + bulkSelectedGrps.Count + " selected Group(s).");
                        } else {
                            EditorGUILayout.Separator();
                        }
                    }
                }

                var isBulkMute = false;
                var isBulkSolo = false;
                float? bulkVolume = null;
                int? bulkBusIndex = null;

                int? busToCreate = null;

                DTGUIHelper.ResetColors();

                for (var l = 0; l < filteredGroups.Count; l++) {
                    EditorGUI.indentLevel = 0;
                    aGroup = filteredGroups[l];

                    var groupDirty = false;
                    var isBulkEdit = bulkSelectedGrps.Count > 0 && aGroup.isSelected;

                    var sType = string.Empty;
                    if (Application.isPlaying) {
                        sType = aGroup.name;
                    }

                    EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                    var groupName = aGroup.name;

                    if (Application.isPlaying) {
                        var groupVoices = aGroup.ActiveVoices;
                        var totalVoices = aGroup.TotalVoices;

                        GUI.color = DTGUIHelper.BrightTextColor;

                        if (groupVoices == 0) {
                            GUI.contentColor = Color.white;
                            GUI.backgroundColor = Color.white;
                            GUI.color = DTGUIHelper.InactiveMixerGroupColor;
                        } else if (groupVoices >= totalVoices) {
                            GUI.contentColor = Color.red;
                            GUI.backgroundColor = Color.red;
                        }

                        if (GUILayout.Button(new GUIContent(string.Format("[{0}]", groupVoices), "Click to select Variations"), EditorStyles.toolbarButton)) {
                            SelectActiveVariationsInGroup(aGroup);
                        }
                        DTGUIHelper.ResetColors();

                        switch (aGroup.GroupLoadStatus) {
                            case MasterAudio.InternetFileLoadStatus.Loading:
                                GUILayout.Button(
                                    new GUIContent(MasterAudioInspectorResources.LoadingTexture,
                                        "Downloading 1 or more Internet Files"), EditorStyles.toolbarButton, GUILayout.Width(24));
                                break;
                            case MasterAudio.InternetFileLoadStatus.Failed:
                                GUILayout.Button(
                                    new GUIContent(MasterAudioInspectorResources.ErrorTexture,
                                        "1 or more Internet Files failed download"), EditorStyles.toolbarButton, GUILayout.Width(24));
                                break;
                            case MasterAudio.InternetFileLoadStatus.Loaded:
                                GUILayout.Button(
                                    new GUIContent(MasterAudioInspectorResources.ReadyTexture,
                                        "All audio is ready to play"), EditorStyles.toolbarButton, GUILayout.Width(24));
                                break;
                        }

                        totalVoiceCount += groupVoices;
                    }

                    if (_sounds.showGroupSelect) {
                        var newChecked = EditorGUILayout.Toggle(aGroup.isSelected, EditorStyles.toggleGroup, GUILayout.Width(16));
                        if (newChecked != aGroup.isSelected) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref groupDirty, aGroup, "toggle Select Group");
                            aGroup.isSelected = newChecked;
                        }
                    }

                    var minWidth = 100;
                    if (_sounds.MixerWidth == MasterAudio.MixerWidthMode.Narrow) {
                        minWidth = NarrowWidth;
                    }

                    EditorGUILayout.LabelField(groupName, EditorStyles.label, GUILayout.MinWidth(minWidth));

                    GUILayout.FlexibleSpace();
                    EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(50));

                    if (_sounds.MixerWidth != MasterAudio.MixerWidthMode.Narrow || _sounds.busesShownInNarrow) {
                        // find bus.
                        var selectedBusIndex = aGroup.busIndex == -1 ? 0 : aGroup.busIndex;

                        GUI.contentColor = Color.white;
                        GUI.color = DTGUIHelper.BrightButtonColor;

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

                        if (aGroup.busIndex != busIndex && busIndex != 1) {
                            if (isBulkEdit) {
                                bulkBusIndex = busIndex;
                            } else {
                                AudioUndoHelper.RecordObjectPropertyForUndo(ref groupDirty, aGroup, "change Group Bus");
                            }
                        }

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

                        GUI.color = Color.white;

                        if (selectedBusIndex != busIndex) {
                            if (busIndex == 0 && Application.isPlaying) {
#if UNITY_5
                                _sounds.RouteGroupToUnityMixerGroup(sType, null);
#endif
                            } else if (busIndex == 1) {
                                busToCreate = l;
                                if (Application.isPlaying) {
#if UNITY_5
                                    _sounds.RouteGroupToUnityMixerGroup(sType, null);
#endif
                                }
                            } else if (busIndex >= MasterAudio.HardCodedBusOptions) {
                                var newBus = _sounds.groupBuses[busIndex - MasterAudio.HardCodedBusOptions];
                                if (Application.isPlaying) {
                                    var statGroup = MasterAudio.GrabGroup(sType);
                                    statGroup.busIndex = busIndex;

                                    if (newBus.isMuted) {
                                        MasterAudio.MuteGroup(aGroup.name);
                                    } else if (newBus.isSoloed) {
                                        MasterAudio.SoloGroup(aGroup.name);
                                    }

                                    // reassign Unity Mixer Group
#if UNITY_5
                                    _sounds.RouteGroupToUnityMixerGroup(sType, newBus.mixerChannel);
#endif
                                } else {
                                    // check if bus soloed or muted.
                                    if (newBus.isMuted) {
                                        aGroup.isMuted = true;
                                        aGroup.isSoloed = false;
                                    } else if (newBus.isSoloed) {
                                        aGroup.isMuted = false;
                                        aGroup.isSoloed = true;
                                    }
                                }
                            }
                        }
                    }

                    GUI.contentColor = DTGUIHelper.BrightTextColor;

                    if (_sounds.MixerWidth != MasterAudio.MixerWidthMode.Narrow) {
                        GUILayout.TextField(
                            DTGUIHelper.DisplayVolumeNumber(aGroup.groupMasterVolume, sliderIndicatorChars),
                            sliderIndicatorChars, EditorStyles.miniLabel, GUILayout.Width(sliderWidth));
                    }

                    var newVol = DTGUIHelper.DisplayVolumeField(aGroup.groupMasterVolume, DTGUIHelper.VolumeFieldType.MixerGroup, _sounds.MixerWidth);
                    if (newVol != aGroup.groupMasterVolume) {
                        if (isBulkEdit) {
                            bulkVolume = newVol;
                        } else {
                            SetMixerGroupVolume(aGroup, ref groupDirty, newVol, false);
                        }
                    }

                    GUI.contentColor = Color.white;
                    DTGUIHelper.AddLedSignalLight(_sounds, groupName);

                    groupButtonPressed = DTGUIHelper.AddMixerButtons(aGroup, "Group");

                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndHorizontal();

                    switch (groupButtonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Find:
                            DTGUIHelper.ShowFilteredRelationsGraph(aGroup.name);
                            break;
                        case DTGUIHelper.DTFunctionButtons.Play:
                            if (Application.isPlaying) {
                                MasterAudio.PlaySoundAndForget(aGroup.name);
                            } else {
                                var rndIndex = Random.Range(0, aGroup.groupVariations.Count);
                                var rndVar = aGroup.groupVariations[rndIndex];

                                var calcVolume = aGroup.groupMasterVolume * rndVar.VarAudio.volume;

                                if (rndVar.audLocation == MasterAudio.AudioLocation.ResourceFile) {
                                    StopPreviewer();
                                    var fileName = AudioResourceOptimizer.GetLocalizedFileName(rndVar.useLocalization, rndVar.resourceFileName);
                                    GetPreviewer().PlayOneShot(Resources.Load(fileName) as AudioClip, calcVolume);
                                } else {
                                    rndVar.VarAudio.PlayOneShot(rndVar.VarAudio.clip, calcVolume);
                                }

                                _isDirty = true;
                            }
                            break;
                        case DTGUIHelper.DTFunctionButtons.Stop:
                            if (Application.isPlaying) {
                                MasterAudio.StopAllOfSound(aGroup.name);
                            } else {
                                var hasResourceFile = false;
                                foreach (var t in aGroup.groupVariations) {
                                    t.VarAudio.Stop();
                                    if (t.audLocation == MasterAudio.AudioLocation.ResourceFile) {
                                        hasResourceFile = true;
                                    }
                                }

                                if (hasResourceFile) {
                                    StopPreviewer();
                                }
                            }
                            break;
                        case DTGUIHelper.DTFunctionButtons.Mute:
                            if (isBulkEdit) {
                                isBulkMute = true;
                            } else {
                                MuteMixerGroup(aGroup, ref groupDirty, false, false);
                            }
                            break;
                        case DTGUIHelper.DTFunctionButtons.Solo:
                            if (isBulkEdit) {
                                isBulkSolo = true;
                            } else {
                                SoloMixerGroup(aGroup, ref groupDirty, false, false);
                            }
                            break;
                        case DTGUIHelper.DTFunctionButtons.Go:
                            Selection.activeObject = aGroup.transform;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            groupToDelete = aGroup.transform.gameObject;
                            break;
                    }

                    if (groupDirty) {
                        EditorUtility.SetDirty(aGroup);
                    }
                }

                if (isBulkMute) {
                    AudioUndoHelper.RecordObjectsForUndo(bulkSelectedGrps.ToArray(), "Bulk Mute");

                    var wasWarningShown = false;

                    foreach (var grp in bulkSelectedGrps) {
                        wasWarningShown = MuteMixerGroup(grp, ref fakeDirty, true, wasWarningShown);
                        EditorUtility.SetDirty(grp);
                    }
                }

                if (isBulkSolo) {
                    AudioUndoHelper.RecordObjectsForUndo(bulkSelectedGrps.ToArray(), "Bulk Solo");

                    var wasWarningShown = false;

                    foreach (var grp in bulkSelectedGrps) {
                        wasWarningShown = SoloMixerGroup(grp, ref fakeDirty, true, wasWarningShown);
                        EditorUtility.SetDirty(grp);
                    }
                }

                if (bulkVolume.HasValue) {
                    AudioUndoHelper.RecordObjectsForUndo(bulkSelectedGrps.ToArray(), "Bulk Volume Adjustment");

                    foreach (var grp in bulkSelectedGrps) {
                        SetMixerGroupVolume(grp, ref fakeDirty, bulkVolume.Value, true);
                        EditorUtility.SetDirty(grp);
                    }
                }

                if (bulkBusIndex.HasValue) {
                    AudioUndoHelper.RecordObjectsForUndo(bulkSelectedGrps.ToArray(), "Bulk Bus Assignment");


                    foreach (var grp in bulkSelectedGrps) {
                        grp.busIndex = bulkBusIndex.Value;
#if UNITY_5
                        if (bulkBusIndex.Value == 0) {
                            _sounds.RouteGroupToUnityMixerGroup(grp.name, null);
                        } else {
                            var theBus = _sounds.groupBuses[bulkBusIndex.Value - MasterAudio.HardCodedBusOptions];
                            if (theBus != null) {
                                _sounds.RouteGroupToUnityMixerGroup(grp.name, theBus.mixerChannel);
                            }
                        }
#endif

                        EditorUtility.SetDirty(grp);
                    }
                }

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

                if (groupToDelete != null) {
                    _sounds.musicDuckingSounds.RemoveAll(delegate(DuckGroupInfo obj) {
                        return obj.soundType == groupToDelete.name;
                    });
                    AudioUndoHelper.DestroyForUndo(groupToDelete);
                }

                if (Application.isPlaying) {
                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Space(9);
                    GUI.color = DTGUIHelper.BrightTextColor;
                    EditorGUILayout.LabelField(string.Format("[{0}] Total Active Voices", totalVoiceCount));
                    GUI.color = Color.white;
                    EditorGUILayout.EndHorizontal();
                }

                EditorGUILayout.Separator();
                EditorGUILayout.BeginHorizontal();

                if (_sounds.MixerWidth != MasterAudio.MixerWidthMode.Narrow) {
                    GUILayout.Space(10);
                }

                GUI.contentColor = DTGUIHelper.BrightButtonColor;
                if (GUILayout.Button(new GUIContent("Mute/Solo Reset", "Turn off all group mute and solo switches"), EditorStyles.toolbarButton, GUILayout.Width(100))) {
                    AudioUndoHelper.RecordObjectsForUndo(groups.ToArray(), "Mute/Solo Reset");

                    foreach (var t in groups) {
                        aGroup = t;
                        aGroup.isSoloed = false;
                        aGroup.isMuted = false;
                    }
                }

                GUILayout.Space(6);

                if (GUILayout.Button(new GUIContent("Max Grp. Volumes", "Reset all group volumes to full"), EditorStyles.toolbarButton, GUILayout.Width(104))) {
                    AudioUndoHelper.RecordObjectsForUndo(groups.ToArray(), "Max Grp. Volumes");

                    foreach (var t in groups) {
                        aGroup = t;
                        aGroup.groupMasterVolume = 1f;
                    }
                }

                GUI.contentColor = Color.white;

                EditorGUILayout.EndHorizontal();

                if (_sounds.MixerWidth == MasterAudio.MixerWidthMode.Narrow) {
                    DTGUIHelper.ShowColorWarning("Some controls are hidden from the Group Mixer in narrow mode.");
                }
            }

            if (selectAll) {
                AudioUndoHelper.RecordObjectsForUndo(filteredGroups.ToArray(), "Select Groups");

                foreach (var myGroup in filteredGroups) {
                    myGroup.isSelected = true;
                }
            }
            if (deselectAll) {
                AudioUndoHelper.RecordObjectsForUndo(filteredGroups.ToArray(), "Deselect Groups");

                foreach (var myGroup in filteredGroups) {
                    myGroup.isSelected = false;
                }
            }
            if (applyAudioSourceTemplate) {
                AudioUndoHelper.RecordObjectsForUndo(filteredGroups.ToArray(), "Apply Audio Source Template");

                foreach (var myGroup in filteredGroups) {
                    if (!myGroup.isSelected) {
                        continue;
                    }

                    for (var v = 0; v < myGroup.transform.childCount; v++) {
#if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
                        Debug.LogError("This feature requires Unity 4 or higher.");
#else
                        var aVar = myGroup.transform.GetChild(v);
                        var oldAudio = aVar.GetComponent<AudioSource>();
                        CopyFromAudioSourceTemplate(oldAudio, true);
#endif
                    }
                }
            }

            if (applyTemplateToAll) {
                AudioUndoHelper.RecordObjectsForUndo(filteredGroups.ToArray(), "Apply Audio Source Template to All");

                foreach (var myGroup in filteredGroups) {
                    for (var v = 0; v < myGroup.transform.childCount; v++) {
#if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
                        Debug.LogError("This feature requires Unity 4 or higher.");
#else
                        var aVar = myGroup.transform.GetChild(v);
                        var oldAudio = aVar.GetComponent<AudioSource>();
                        CopyFromAudioSourceTemplate(oldAudio, true);
#endif
                    }
                }
            }
            EditorGUILayout.EndVertical();
            // Sound Groups End

            // Buses
            if (_sounds.groupBuses.Count > 0) {
                DTGUIHelper.VerticalSpace(3);

                var voiceLimitedBuses = _sounds.groupBuses.FindAll(delegate(GroupBus obj) {
                    return obj.voiceLimit >= 0;
                });

                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("Bus Control", GUILayout.Width(74));
                if (voiceLimitedBuses.Count > 0) {
                    GUILayout.FlexibleSpace();
                    GUILayout.Label("Stop Oldest", GUILayout.Width(100));
                    var endSpace = 284;
                    switch (_sounds.MixerWidth) {
                        case MasterAudio.MixerWidthMode.Wide:
                            endSpace = 488;
                            break;
                        case MasterAudio.MixerWidthMode.Narrow:
                            endSpace = 214;
                            break;
                    }
                    GUILayout.Space(endSpace);
                }
                DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/GroupMixer.htm#BusMixer", true);
                EditorGUILayout.EndHorizontal();

                GroupBus aBus = null;
                var busButtonPressed = DTGUIHelper.DTFunctionButtons.None;
                int? busToDelete = null;
                int? busToSolo = null;
                int? busToMute = null;
                int? busToStop = null;

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

                    DTGUIHelper.StartGroupHeader(1, false);

                    if (_sounds.ShouldShowUnityAudioMixerGroupAssignments) {
                        EditorGUILayout.BeginVertical();
                        EditorGUILayout.BeginHorizontal();
                    } else {
                        EditorGUILayout.BeginHorizontal();
                    }

                    GUI.color = Color.gray;

                    if (Application.isPlaying) {
                        GUI.color = DTGUIHelper.BrightTextColor;
                        if (aBus.BusVoiceLimitReached) {
                            GUI.contentColor = Color.red;
                            GUI.backgroundColor = Color.red;
                        }
                        if (GUILayout.Button(string.Format("[{0:D2}]", aBus.ActiveVoices), EditorStyles.toolbarButton)) {
                            SelectActiveVariationsInBus(aBus);
                        }
                        DTGUIHelper.ResetColors();
                    }

                    GUI.color = Color.white;
                    var nameWidth = 170;
                    if (_sounds.MixerWidth == MasterAudio.MixerWidthMode.Narrow) {
                        nameWidth = NarrowWidth;
                    }

                    var newBusName = EditorGUILayout.TextField("", aBus.busName, GUILayout.MinWidth(nameWidth));
                    if (newBusName != aBus.busName) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Bus Name");
                        aBus.busName = newBusName;
                    }

                    GUILayout.FlexibleSpace();
                    if (voiceLimitedBuses.Contains(aBus)) {
                        GUI.color = DTGUIHelper.BrightButtonColor;
                        var newMono = GUILayout.Toggle(aBus.stopOldest, new GUIContent("", "Checking this box will make it so when the voice limit is already reached and you play a sound, the oldest sound will first be stopped."));
                        if (newMono != aBus.stopOldest) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Stop Oldest");
                            aBus.stopOldest = newMono;
                        }
                    }

                    GUI.color = Color.white;
                    GUILayout.Label("Voices");

                    GUI.color = DTGUIHelper.BrightButtonColor;
                    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) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Bus Voice Limit");
                        aBus.voiceLimit = busVoiceLimitIndex <= 0 ? -1 : busVoiceLimitIndex;
                    }

                    GUI.color = Color.white;

                    EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(50));

                    if (_sounds.MixerWidth != MasterAudio.MixerWidthMode.Narrow) {
                        GUI.color = DTGUIHelper.BrightTextColor;
                        GUILayout.TextField(DTGUIHelper.DisplayVolumeNumber(aBus.volume, sliderIndicatorChars),
                            sliderIndicatorChars, EditorStyles.miniLabel, GUILayout.Width(sliderWidth));
                    }

                    GUI.color = Color.white;
                    var newBusVol = DTGUIHelper.DisplayVolumeField(aBus.volume, DTGUIHelper.VolumeFieldType.Bus, _sounds.MixerWidth);
                    if (newBusVol != aBus.volume) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Bus Volume");
                        aBus.volume = newBusVol;
                        if (Application.isPlaying) {
                            MasterAudio.SetBusVolumeByName(aBus.busName, aBus.volume);
                        }
                    }

                    GUI.contentColor = Color.white;

                    busButtonPressed = DTGUIHelper.AddMixerBusButtons(aBus);

                    switch (busButtonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            busToDelete = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Solo:
                            busToSolo = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Mute:
                            busToMute = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Stop:
                            busToStop = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Find:
                            DTGUIHelper.ShowFilteredRelationsGraph(null, aBus.busName);
                            break;
                    }

                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndHorizontal();

#if UNITY_5
                    if (_sounds.ShouldShowUnityAudioMixerGroupAssignments) {
                        var newChan = (AudioMixerGroup)EditorGUILayout.ObjectField(aBus.mixerChannel, typeof(AudioMixerGroup), false);
                        if (newChan != aBus.mixerChannel) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Bus Mixer Group");
                            aBus.mixerChannel = newChan;
                            _sounds.RouteBusToUnityMixerGroup(aBus.busName, newChan);
                        }
                        EditorGUILayout.EndVertical();
                    }

                    if (_sounds.mixerSpatialBlendType != MasterAudio.AllMixerSpatialBlendType.ForceAllTo2D) {
                        var new2D = GUILayout.Toggle(aBus.forceTo2D, "Force to 2D");
                        if (new2D != aBus.forceTo2D) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Force to 2D");
                            aBus.forceTo2D = new2D;
                        }
                    }

#endif
                    EditorGUILayout.EndVertical();
                    DTGUIHelper.AddSpaceForNonU5(2);
                }

                if (busToDelete.HasValue) {
                    DeleteBus(busToDelete.Value);
                }
                if (busToMute.HasValue) {
                    MuteBus(busToMute.Value);
                }
                if (busToSolo.HasValue) {
                    SoloBus(busToSolo.Value);
                }
                if (busToStop.HasValue) {
                    MasterAudio.StopBus(_sounds.groupBuses[busToStop.Value].busName);
                }

                if (Application.isPlaying) {
                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Space(9);
                    GUI.color = DTGUIHelper.BrightTextColor;
                    EditorGUILayout.LabelField(string.Format("[{0:D2}] Total Active Voices", totalVoiceCount));
                    GUI.color = Color.white;
                    EditorGUILayout.EndHorizontal();
                }

                EditorGUILayout.Separator();
                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(10);
                GUI.contentColor = DTGUIHelper.BrightButtonColor;
                GUI.backgroundColor = Color.white;

                if (GUILayout.Button(new GUIContent("Mute/Solo Reset", "Turn off all bus mute and solo switches"), EditorStyles.toolbarButton, GUILayout.Width(100))) {
                    BusMuteSoloReset();
                }

                GUILayout.Space(6);

                if (GUILayout.Button(new GUIContent("Max Bus Volumes", "Reset all bus volumes to full"), EditorStyles.toolbarButton, GUILayout.Width(100))) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "Max Bus Volumes");

                    foreach (var t in _sounds.groupBuses) {
                        aBus = t;
                        aBus.volume = 1f;
                    }
                }

#if UNITY_5
                GUILayout.Space(6);

                GUI.contentColor = DTGUIHelper.BrightButtonColor;
                var buttonText = "Show Unity Mixer Groups";
                if (_sounds.showUnityMixerGroupAssignment) {
                    buttonText = "Hide Unity Mixer Groups";
                }
                if (GUILayout.Button(new GUIContent(buttonText), EditorStyles.toolbarButton, GUILayout.Width(140))) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, buttonText);
                    _sounds.showUnityMixerGroupAssignment = !_sounds.showUnityMixerGroupAssignment;
                }
#endif

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

            DTGUIHelper.EndGroupedControls();
        }
        // Sound Buses End

        // Music playlist Start		
        DTGUIHelper.VerticalSpace(3);
        EditorGUILayout.BeginHorizontal();
        EditorGUI.indentLevel = 0;  // Space will handle this for the header

        DTGUIHelper.ResetColors();


        state = _sounds.playListExpanded;
        text = "Playlist Settings";

        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
        if (!state) {
            GUI.backgroundColor = DTGUIHelper.InactiveHeaderColor;
        } else {
            GUI.backgroundColor = DTGUIHelper.ActiveHeaderColor;
        }

        GUILayout.BeginHorizontal();

#if UNITY_3_5_7
        if (!state) {
            text += " (Click to expand)";
        }
#else
        text = "<b><size=11>" + text + "</size></b>";
#endif
        if (state) {
            text = "\u25BC " + text;
        } else {
            text = "\u25BA " + text;
        }
        if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) {
            state = !state;
        }

        GUILayout.Space(2f);

        var isExp = state;


        if (isExp != _sounds.playListExpanded) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Playlist Settings");
            _sounds.playListExpanded = isExp;
        }

        DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/PlaylistSettings.htm");

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

        EditorGUILayout.EndHorizontal();


        if (_sounds.playListExpanded) {
            DTGUIHelper.BeginGroupedControls();

            if (_sounds.MixerWidth == MasterAudio.MixerWidthMode.Narrow) {
                DTGUIHelper.ShowColorWarning("Some controls are hidden from Playlist Control in narrow mode.");
            }

#if UNITY_5
            DTGUIHelper.StartGroupHeader(1, false);
            var newMusicSpatialType = (MasterAudio.AllMusicSpatialBlendType)EditorGUILayout.EnumPopup("Music Spatial Blend Rule", _sounds.musicSpatialBlendType);
            if (newMusicSpatialType != _sounds.musicSpatialBlendType) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Music Spatial Blend Rule");
                _sounds.musicSpatialBlendType = newMusicSpatialType;

                if (Application.isPlaying) {
                    SetSpatialBlendsForPlaylistControllers();
                } else {
                    SetSpatialBlendForPlaylistsEdit();
                }
            }

            switch (_sounds.musicSpatialBlendType) {
                case MasterAudio.AllMusicSpatialBlendType.ForceAllToCustom:
                    DTGUIHelper.ShowLargeBarAlert(SpatialBlendSliderText);
                    var newMusic3D = EditorGUILayout.Slider("Music Spatial Blend", _sounds.musicSpatialBlend, 0f, 1f);
                    if (newMusic3D != _sounds.musicSpatialBlend) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Music Spatial Blend");
                        _sounds.musicSpatialBlend = newMusic3D;
                        if (Application.isPlaying) {
                            SetSpatialBlendsForPlaylistControllers();
                        } else {
                            SetSpatialBlendForPlaylistsEdit();
                        }
                    }
                    break;
                case MasterAudio.AllMusicSpatialBlendType.AllowDifferentPerController:
                    DTGUIHelper.ShowLargeBarAlert("To set Spatial Blend, go to each Playlist Controller and change it there.");
                    break;
            }
            EditorGUILayout.EndVertical();

            EditorGUILayout.Separator();
#endif

            EditorGUI.indentLevel = 0;  // Space will handle this for the header
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Playlist Controller Setup", EditorStyles.miniBoldLabel, GUILayout.Width(130));

            DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/PlaylistSettings.htm#PlaylistControllerSetup", true);
            EditorGUILayout.EndHorizontal();

            EditorGUI.indentLevel = 0;
            DTGUIHelper.StartGroupHeader();
            EditorGUILayout.BeginHorizontal();
            const string labelText = "Name";
            labelWidth = 146;
            if (_sounds.MixerWidth == MasterAudio.MixerWidthMode.Narrow) {
                labelWidth = NarrowWidth;
            }
            EditorGUILayout.LabelField(labelText, EditorStyles.miniBoldLabel, GUILayout.Width(labelWidth));
            if (plControllerInScene) {
                GUILayout.FlexibleSpace();
                if (_sounds.MixerWidth != MasterAudio.MixerWidthMode.Narrow) {
                    EditorGUILayout.LabelField("Sync Grp.", EditorStyles.miniBoldLabel, GUILayout.Width(54));
                }
                EditorGUILayout.LabelField("Initial Playlist", EditorStyles.miniBoldLabel, GUILayout.Width(100));
                var endLength = 208;
                if (Application.isPlaying) {
                    endLength = 182;
                }
                if (_sounds.MixerWidth == MasterAudio.MixerWidthMode.Narrow) {
                    endLength -= 58;
                }

                GUILayout.Space(endLength - extraPlaylistLength);
            }
            EditorGUILayout.EndHorizontal();

            if (!plControllerInScene) {
                DTGUIHelper.ShowLargeBarAlert("There are no Playlist Controllers in the scene. Music will not play.");
            } else {
                int? indexToDelete = null;

                _playlistNames.Insert(0, MasterAudio.NoPlaylistName);

                var syncGroupList = new List<string>();
                for (var i = 0; i < 4; i++) {
                    syncGroupList.Add((i + 1).ToString());
                }
                syncGroupList.Insert(0, MasterAudio.NoGroupName);

                for (var i = 0; i < pcs.Count; i++) {
                    var controller = pcs[i];
                    DTGUIHelper.StartGroupHeader(1, false);

#if UNITY_5
                    EditorGUILayout.BeginVertical();
                    EditorGUILayout.BeginHorizontal();
#else
                    EditorGUILayout.BeginHorizontal();
#endif

                    GUILayout.Label(controller.name, _sounds.MixerWidth == MasterAudio.MixerWidthMode.Narrow ? GUILayout.MinWidth(NarrowWidth) : GUILayout.MinWidth(105));

                    GUILayout.FlexibleSpace();

                    var ctrlDirty = false;

                    if (_sounds.MixerWidth != MasterAudio.MixerWidthMode.Narrow) {
                        GUI.color = DTGUIHelper.BrightButtonColor;
                        var syncIndex = syncGroupList.IndexOf(controller.syncGroupNum.ToString());
                        if (syncIndex == -1) {
                            syncIndex = 0;
                        }
                        var newSync = EditorGUILayout.Popup("", syncIndex, syncGroupList.ToArray(), GUILayout.Width(55));
                        if (newSync != syncIndex) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref ctrlDirty, controller,
                                "change Controller Sync Group");
                            controller.syncGroupNum = newSync;
                        }
                    }

                    var origIndex = _playlistNames.IndexOf(controller.startPlaylistName);
                    var isCustomPlaylist = false;
                    if (origIndex == -1) {
                        if (string.IsNullOrEmpty(controller.startPlaylistName) || controller.startPlaylistName.StartsWith("[")) {
                            origIndex = 0;
                            controller.startPlaylistName = string.Empty;
                        } else {
                            isCustomPlaylist = true;
                        }
                    }

                    if (isCustomPlaylist) {
                        EditorGUILayout.LabelField(controller.startPlaylistName, GUILayout.Width(playlistListWidth));
                    } else {
                        var newIndex = EditorGUILayout.Popup("", origIndex, _playlistNames.ToArray(),
                                GUILayout.Width(playlistListWidth));
                        if (newIndex != origIndex) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref ctrlDirty, controller,
                                "change Playlist Controller initial Playlist");
                            controller.startPlaylistName = _playlistNames[newIndex];
                        }
                    }
                    GUI.color = Color.white;

                    if (_sounds.MixerWidth != MasterAudio.MixerWidthMode.Narrow) {
                        GUI.contentColor = DTGUIHelper.BrightButtonColor;
                        GUILayout.TextField(
                            DTGUIHelper.DisplayVolumeNumber(controller._playlistVolume, sliderIndicatorChars),
                            sliderIndicatorChars, EditorStyles.miniLabel, GUILayout.Width(sliderWidth));
                    }
                    var newVol = DTGUIHelper.DisplayVolumeField(controller._playlistVolume, DTGUIHelper.VolumeFieldType.PlaylistController, _sounds.MixerWidth);

                    if (newVol != controller._playlistVolume) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref ctrlDirty, controller, "change Playlist Controller volume");
                        controller.PlaylistVolume = newVol;
                    }

                    GUI.contentColor = Color.white;

                    var buttonPressed = DTGUIHelper.AddPlaylistControllerSetupButtons(controller, "Playlist Controller", false);

                    EditorGUILayout.EndHorizontal();

#if UNITY_5
                    if (_sounds.showUnityMixerGroupAssignment) {
                        var newChan = (AudioMixerGroup)EditorGUILayout.ObjectField(controller.mixerChannel, typeof(AudioMixerGroup), false);
                        if (newChan != controller.mixerChannel) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref ctrlDirty, controller, "change Playlist Controller Unity Mixer Group");
                            controller.mixerChannel = newChan;

                            if (Application.isPlaying) {
                                controller.RouteToMixerChannel(newChan);
                            }
                        }
                    }

                    EditorGUILayout.EndVertical();
#endif

                    switch (buttonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Go:
                            Selection.activeObject = controller.transform;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            indexToDelete = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Mute:
                            controller.ToggleMutePlaylist();
                            ctrlDirty = true;
                            break;
                    }

                    EditorGUILayout.EndVertical();
                    DTGUIHelper.AddSpaceForNonU5(1);

                    if (ctrlDirty) {
                        EditorUtility.SetDirty(controller);
                    }
                }

                if (indexToDelete.HasValue) {
                    AudioUndoHelper.DestroyForUndo(pcs[indexToDelete.Value].gameObject);
                }
            }

            EditorGUILayout.Separator();
            GUI.contentColor = DTGUIHelper.BrightButtonColor;
            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(10);
            GUI.backgroundColor = Color.white;
            if (GUILayout.Button(new GUIContent("Create Playlist Controller"), EditorStyles.toolbarButton, GUILayout.Width(150))) {
                // ReSharper disable once RedundantCast
                var go = (GameObject)Instantiate(_sounds.playlistControllerPrefab.gameObject);
                go.name = "PlaylistController";

                AudioUndoHelper.CreateObjectForUndo(go, "create Playlist Controller");
            }

            var buttonText = string.Empty;

#if UNITY_5
            GUILayout.Space(6);
            GUI.contentColor = DTGUIHelper.BrightButtonColor;
            buttonText = "Show Unity Mixer Groups";
            if (_sounds.showUnityMixerGroupAssignment) {
                buttonText = "Hide Unity Mixer Groups";
            }
            if (GUILayout.Button(new GUIContent(buttonText), EditorStyles.toolbarButton, GUILayout.Width(140))) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, buttonText);
                _sounds.showUnityMixerGroupAssignment = !_sounds.showUnityMixerGroupAssignment;
            }
#endif

            EditorGUILayout.EndHorizontal();
            DTGUIHelper.EndGroupHeader();

            GUI.contentColor = Color.white;

            EditorGUILayout.Separator();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Playlist Setup", EditorStyles.miniBoldLabel, GUILayout.Width(80));
            DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/PlaylistSettings.htm#PlaylistSetup", true);
            EditorGUILayout.EndHorizontal();

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

            if (_sounds.musicPlaylists.Count == 0) {
                DTGUIHelper.ShowLargeBarAlert("You currently have no Playlists set up.");
            }

            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
            EditorGUI.indentLevel = 1;
            var oldPlayExpanded = DTGUIHelper.Foldout(_sounds.playlistsExpanded, string.Format("Playlists ({0})", _sounds.musicPlaylists.Count));
            if (oldPlayExpanded != _sounds.playlistsExpanded) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Playlists");
                _sounds.playlistsExpanded = oldPlayExpanded;
            }

            EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(100));

            var addPressed = false;

            buttonText = "Click to add new Playlist at the end";
            // Add button - Process presses later
            GUI.contentColor = DTGUIHelper.BrightButtonColor;
            addPressed = GUILayout.Button(new GUIContent("Add", buttonText),
                                               EditorStyles.toolbarButton);
            GUIContent content;
            GUI.contentColor = DTGUIHelper.BrightButtonColor;

            content = new GUIContent("Collapse", "Click to collapse all");
            var masterCollapse = GUILayout.Button(content, EditorStyles.toolbarButton);

            content = new GUIContent("Expand", "Click to expand all");
            var masterExpand = GUILayout.Button(content, EditorStyles.toolbarButton);
            if (masterExpand) {
                ExpandCollapseAllPlaylists(true);
            }
            if (masterCollapse) {
                ExpandCollapseAllPlaylists(false);
            }
            GUI.contentColor = Color.white;
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndHorizontal();

            if (_sounds.playlistsExpanded) {
                int? playlistToRemove = null;
                int? playlistToInsertAt = null;
                int? playlistToMoveUp = null;
                int? playlistToMoveDown = null;

                for (var i = 0; i < _sounds.musicPlaylists.Count; i++) {
                    var aList = _sounds.musicPlaylists[i];

                    DTGUIHelper.StartGroupHeader();

                    EditorGUI.indentLevel = 1;
                    EditorGUILayout.BeginHorizontal();
                    aList.isExpanded = DTGUIHelper.Foldout(aList.isExpanded, "Playlist: " + aList.playlistName);

                    var playlistButtonPressed = DTGUIHelper.AddFoldOutListItemButtonItems(i, _sounds.musicPlaylists.Count, "playlist", false, false, true);

                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndVertical();

                    if (aList.isExpanded) {
                        EditorGUI.indentLevel = 0;
                        var newPlaylist = EditorGUILayout.TextField("Name", aList.playlistName);
                        if (newPlaylist != aList.playlistName) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Name");
                            aList.playlistName = newPlaylist;
                        }

                        var crossfadeMode = (MasterAudio.Playlist.CrossfadeTimeMode)EditorGUILayout.EnumPopup("Crossfade Mode", aList.crossfadeMode);
                        if (crossfadeMode != aList.crossfadeMode) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Crossfade Mode");
                            aList.crossfadeMode = crossfadeMode;
                        }
                        if (aList.crossfadeMode == MasterAudio.Playlist.CrossfadeTimeMode.Override) {
                            var newCf = EditorGUILayout.Slider("Crossfade time (sec)", aList.crossFadeTime, 0f, MasterAudio.MaxCrossFadeTimeSeconds);
                            if (newCf != aList.crossFadeTime) {
                                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Crossfade time (sec)");
                                aList.crossFadeTime = newCf;
                            }
                        }

                        var newFadeIn = EditorGUILayout.Toggle("Fade In First Song", aList.fadeInFirstSong);
                        if (newFadeIn != aList.fadeInFirstSong) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Fade In First Song");
                            aList.fadeInFirstSong = newFadeIn;
                        }

                        var newFadeOut = EditorGUILayout.Toggle("Fade Out Last Song", aList.fadeOutLastSong);
                        if (newFadeOut != aList.fadeOutLastSong) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Fade Out Last Song");
                            aList.fadeOutLastSong = newFadeOut;
                        }

                        var newTransType = (MasterAudio.SongFadeInPosition)EditorGUILayout.EnumPopup("Song Transition Type", aList.songTransitionType);
                        if (newTransType != aList.songTransitionType) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Song Transition Type");
                            aList.songTransitionType = newTransType;
                        }
                        if (aList.songTransitionType == MasterAudio.SongFadeInPosition.SynchronizeClips) {
                            DTGUIHelper.ShowColorWarning("All clips must be of exactly the same length in this mode.");
                        }

                        EditorGUI.indentLevel = 0;
                        var newBulkMode = DTGUIHelper.GetRestrictedAudioLocation("Clip Create Mode", aList.bulkLocationMode);
                        if (newBulkMode != aList.bulkLocationMode) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Bulk Clip Mode");
                            aList.bulkLocationMode = newBulkMode;
                        }

                        var playlistHasResource = false;
                        foreach (var t in aList.MusicSettings) {
                            if (t.audLocation != MasterAudio.AudioLocation.ResourceFile) {
                                continue;
                            }

                            playlistHasResource = true;
                            break;
                        }

                        if (MasterAudio.HasAsyncResourceLoaderFeature() && playlistHasResource) {
                            if (!_sounds.resourceClipsAllLoadAsync) {
                                var newAsync = EditorGUILayout.Toggle(new GUIContent("Load Resources Async", "Checking this means Resource files in this Playlist will be loaded asynchronously."), aList.resourceClipsAllLoadAsync);
                                if (newAsync != aList.resourceClipsAllLoadAsync) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Load Resources Async");
                                    aList.resourceClipsAllLoadAsync = newAsync;
                                }
                            }
                        }

                        EditorGUILayout.BeginHorizontal();
                        GUILayout.Space(10);
                        GUI.contentColor = DTGUIHelper.BrightButtonColor;
                        if (GUILayout.Button(new GUIContent("Eq. Song Volumes"), EditorStyles.toolbarButton, GUILayout.Width(110))) {
                            EqualizePlaylistVolumes(aList.MusicSettings);
                        }

                        var hasExpanded = false;
                        foreach (var t in aList.MusicSettings) {
                            if (!t.isExpanded) {
                                continue;
                            }

                            hasExpanded = true;
                            break;
                        }

                        var theButtonText = hasExpanded ? "Collapse All" : "Expand All";

                        GUILayout.Space(10);
                        GUI.contentColor = DTGUIHelper.BrightButtonColor;
                        if (GUILayout.Button(new GUIContent(theButtonText), EditorStyles.toolbarButton, GUILayout.Width(76))) {
                            ExpandCollapseSongs(aList, !hasExpanded);
                        }
                        GUILayout.Space(10);
                        if (GUILayout.Button(new GUIContent("Sort Alpha"), EditorStyles.toolbarButton, GUILayout.Width(70))) {
                            SortSongsAlpha(aList);
                        }

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

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

                        GUI.color = DTGUIHelper.DragAreaColor;

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

                        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;
                                        }

                                        AddSongToPlaylist(aList, aClip);
                                    }
                                }
                                Event.current.Use();
                                break;
                        }
                        EditorGUILayout.EndVertical();

                        EditorGUI.indentLevel = 2;

                        int? addIndex = null;
                        int? removeIndex = null;
                        int? moveUpIndex = null;
                        int? moveDownIndex = null;
                        int? indexToClone = null;

                        if (aList.MusicSettings.Count == 0) {
                            EditorGUI.indentLevel = 0;
                            DTGUIHelper.ShowLargeBarAlert("You currently have no songs in this Playlist.");
                        }

                        EditorGUI.indentLevel = 0;
                        for (var j = 0; j < aList.MusicSettings.Count; j++) {
                            DTGUIHelper.StartGroupHeader(1);

                            var aSong = aList.MusicSettings[j];
                            var clipName = "Empty";
                            switch (aSong.audLocation) {
                                case MasterAudio.AudioLocation.Clip:
                                    if (aSong.clip != null) {
                                        clipName = aSong.clip.name;
                                    }
                                    break;
                                case MasterAudio.AudioLocation.ResourceFile:
                                    if (!string.IsNullOrEmpty(aSong.resourceFileName)) {
                                        clipName = aSong.resourceFileName;
                                    }
                                    break;
                            }
                            EditorGUILayout.BeginHorizontal();
                            EditorGUI.indentLevel = 1;

                            aSong.songName = aSong.alias;
                            if (!string.IsNullOrEmpty(clipName) && string.IsNullOrEmpty(aSong.songName)) {
                                switch (aSong.audLocation) {
                                    case MasterAudio.AudioLocation.Clip:
                                        aSong.songName = clipName;
                                        break;
                                    case MasterAudio.AudioLocation.ResourceFile:
                                        aSong.songName = clipName;
                                        break;
                                }
                            }

                            var newSongExpanded = DTGUIHelper.Foldout(aSong.isExpanded, aSong.songName);
                            if (newSongExpanded != aSong.isExpanded) {
                                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Song expand");
                                aSong.isExpanded = newSongExpanded;
                            }

                            var songButtonPressed = DTGUIHelper.AddFoldOutListItemButtonItems(j, aList.MusicSettings.Count, "clip", false, true, true, allowPreview);
                            GUILayout.Space(4);
                            DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/PlaylistSettings.htm#Song");
                            EditorGUILayout.EndHorizontal();
                            EditorGUILayout.EndVertical();

                            if (aSong.isExpanded) {
                                EditorGUI.indentLevel = 0;

                                var newName = EditorGUILayout.TextField(new GUIContent("Song Id (optional)", "When you 'Play song by name', Song Id's will be searched first before audio file name."), aSong.alias);
                                if (newName != aSong.alias) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Song Id");
                                    aSong.alias = newName;
                                }

                                var oldLocation = aSong.audLocation;
                                var newClipSource = DTGUIHelper.GetRestrictedAudioLocation("Audio Origin", aSong.audLocation);
                                if (newClipSource != aSong.audLocation) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Audio Origin");
                                    aSong.audLocation = newClipSource;
                                }

                                switch (aSong.audLocation) {
                                    case MasterAudio.AudioLocation.Clip:
                                        var newClip = (AudioClip)EditorGUILayout.ObjectField("Audio Clip", aSong.clip, typeof(AudioClip), true);
                                        if (newClip != aSong.clip) {
                                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Clip");
                                            aSong.clip = newClip;
                                            var cName = newClip == null ? "Empty" : newClip.name;
                                            aSong.songName = cName;
                                        }
                                        break;
                                    case MasterAudio.AudioLocation.ResourceFile:
                                        if (oldLocation != aSong.audLocation) {
                                            if (aSong.clip != null) {
                                                Debug.Log("Audio clip removed to prevent unnecessary memory usage on Resource file Playlist clip.");
                                            }
                                            aSong.clip = null;
                                            aSong.songName = string.Empty;
                                        }

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

                                        GUI.color = DTGUIHelper.DragAreaColor;
                                        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;
                                                        }

                                                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Resource Filename");

                                                        var unused = false;
                                                        var resourceFileName = DTGUIHelper.GetResourcePath(aClip, ref unused, true);
                                                        if (string.IsNullOrEmpty(resourceFileName)) {
                                                            resourceFileName = aClip.name;
                                                        }

                                                        aSong.resourceFileName = resourceFileName;
                                                        aSong.songName = aClip.name;
                                                    }
                                                }
                                                Event.current.Use();
                                                break;
                                        }
                                        EditorGUILayout.EndVertical();

                                        var newFilename = EditorGUILayout.TextField("Resource Filename", aSong.resourceFileName);
                                        if (newFilename != aSong.resourceFileName) {
                                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Resource Filename");
                                            aSong.resourceFileName = newFilename;
                                        }

                                        break;
                                }

                                var newVol = DTGUIHelper.DisplayVolumeField(aSong.volume, DTGUIHelper.VolumeFieldType.None, _sounds.MixerWidth, 0f, true);
                                if (newVol != aSong.volume) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Volume");
                                    aSong.volume = newVol;
                                }

                                var newPitch = DTGUIHelper.DisplayPitchField(aSong.pitch);
                                if (newPitch != aSong.pitch) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Pitch");
                                    aSong.pitch = newPitch;
                                }

                                var crossFadetime = MasterAudio.Instance.MasterCrossFadeTime;
                                if (aList.crossfadeMode == MasterAudio.Playlist.CrossfadeTimeMode.Override) {
                                    crossFadetime = aList.crossFadeTime;
                                }

                                if (aList.songTransitionType == MasterAudio.SongFadeInPosition.SynchronizeClips && crossFadetime > 0) {
                                    DTGUIHelper.ShowLargeBarAlert("All songs must loop in Synchronized Playlists when crossfade time is not zero. Auto-advance is disabled.");
                                } else {
                                    var newLoop = EditorGUILayout.Toggle("Loop Clip", aSong.isLoop);
                                    if (newLoop != aSong.isLoop) {
                                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Loop Clip");
                                        aSong.isLoop = newLoop;
                                    }
                                }

                                if (aList.songTransitionType == MasterAudio.SongFadeInPosition.NewClipFromBeginning) {
                                    var newStart = EditorGUILayout.FloatField("Start Time (seconds)", aSong.customStartTime, GUILayout.Width(300));
                                    if (newStart < 0) {
                                        newStart = 0f;
                                    }
                                    if (newStart != aSong.customStartTime) {
                                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Start Time (seconds)");
                                        aSong.customStartTime = newStart;
                                    }
                                }

                                GUI.color = Color.white;
                                var exp = EditorGUILayout.BeginToggleGroup(" Fire 'Song Started' Event", aSong.songStartedEventExpanded);
                                if (exp != aSong.songStartedEventExpanded) {
                                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle expand Fire 'Song Started' Event");
                                    aSong.songStartedEventExpanded = exp;
                                }
                                GUI.color = Color.white;

                                if (aSong.songStartedEventExpanded) {
                                    EditorGUI.indentLevel = 1;
                                    DTGUIHelper.ShowColorWarning("When song starts, fire Custom Event below.");

                                    var existingIndex = _sounds.CustomEventNames.IndexOf(aSong.songStartedCustomEvent);

                                    int? customEventIndex = null;

                                    var noEvent = false;
                                    var noMatch = false;

                                    if (existingIndex >= 1) {
                                        customEventIndex = EditorGUILayout.Popup("Custom Event Name", existingIndex, _sounds.CustomEventNames.ToArray());
                                        if (existingIndex == 1) {
                                            noEvent = true;
                                        }
                                    } else if (existingIndex == -1 && aSong.songStartedCustomEvent == MasterAudio.NoGroupName) {
                                        customEventIndex = EditorGUILayout.Popup("Custom Event Name", existingIndex, _sounds.CustomEventNames.ToArray());
                                    } else { // non-match
                                        noMatch = true;
                                        var newEventName = EditorGUILayout.TextField("Custom Event Name", aSong.songStartedCustomEvent);
                                        if (newEventName != aSong.songStartedCustomEvent) {
                                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Custom Event Name");
                                            aSong.songStartedCustomEvent = newEventName;
                                        }

                                        var newIndex = EditorGUILayout.Popup("All Custom Events", -1, _sounds.CustomEventNames.ToArray());
                                        if (newIndex >= 0) {
                                            customEventIndex = newIndex;
                                        }
                                    }

                                    if (noEvent) {
                                        DTGUIHelper.ShowRedError("No Custom Event specified. This section will do nothing.");
                                    } else if (noMatch) {
                                        DTGUIHelper.ShowRedError("Custom Event found no match. Type in or choose one.");
                                    }

                                    if (customEventIndex.HasValue) {
                                        if (existingIndex != customEventIndex.Value) {
                                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Custom Event");
                                        }
                                        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                                        if (customEventIndex.Value == -1) {
                                            aSong.songStartedCustomEvent = MasterAudio.NoGroupName;
                                        } else {
                                            aSong.songStartedCustomEvent = _sounds.CustomEventNames[customEventIndex.Value];
                                        }
                                    }
                                }
                                EditorGUILayout.EndToggleGroup();

                                EditorGUI.indentLevel = 0;

                                if (_sounds.useGaplessPlaylists) {
                                    DTGUIHelper.ShowLargeBarAlert("Song Changed Event cannot be used with gapless transitions.");
                                } else {
                                    exp = EditorGUILayout.BeginToggleGroup(" Fire 'Song Changed' Event", aSong.songChangedEventExpanded);
                                    if (exp != aSong.songChangedEventExpanded) {
                                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle expand Fire 'Song Changed' Event");
                                        aSong.songChangedEventExpanded = exp;
                                    }
                                    GUI.color = Color.white;

                                    if (aSong.songChangedEventExpanded) {
                                        EditorGUI.indentLevel = 1;
                                        DTGUIHelper.ShowColorWarning("When song changes to another, fire Custom Event below.");

                                        var existingIndex = _sounds.CustomEventNames.IndexOf(aSong.songChangedCustomEvent);

                                        int? customEventIndex = null;

                                        var noEvent = false;
                                        var noMatch = false;

                                        if (existingIndex >= 1) {
                                            customEventIndex = EditorGUILayout.Popup("Custom Event Name", existingIndex, _sounds.CustomEventNames.ToArray());
                                            if (existingIndex == 1) {
                                                noEvent = true;
                                            }
                                        } else if (existingIndex == -1 && aSong.songChangedCustomEvent == MasterAudio.NoGroupName) {
                                            customEventIndex = EditorGUILayout.Popup("Custom Event Name", existingIndex, _sounds.CustomEventNames.ToArray());
                                        } else { // non-match
                                            noMatch = true;
                                            var newEventName = EditorGUILayout.TextField("Custom Event Name", aSong.songChangedCustomEvent);
                                            if (newEventName != aSong.songChangedCustomEvent) {
                                                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Custom Event Name");
                                                aSong.songChangedCustomEvent = newEventName;
                                            }

                                            var newIndex = EditorGUILayout.Popup("All Custom Events", -1, _sounds.CustomEventNames.ToArray());
                                            if (newIndex >= 0) {
                                                customEventIndex = newIndex;
                                            }
                                        }

                                        if (noEvent) {
                                            DTGUIHelper.ShowRedError("No Custom Event specified. This section will do nothing.");
                                        } else if (noMatch) {
                                            DTGUIHelper.ShowRedError("Custom Event found no match. Type in or choose one.");
                                        }

                                        if (customEventIndex.HasValue) {
                                            if (existingIndex != customEventIndex.Value) {
                                                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Custom Event");
                                            }
                                            // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                                            if (customEventIndex.Value == -1) {
                                                aSong.songChangedCustomEvent = MasterAudio.NoGroupName;
                                            } else {
                                                aSong.songChangedCustomEvent = _sounds.CustomEventNames[customEventIndex.Value];
                                            }
                                        }
                                    }
                                    EditorGUILayout.EndToggleGroup();
                                }
                            }

                            switch (songButtonPressed) {
                                case DTGUIHelper.DTFunctionButtons.Add:
                                    addIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.Remove:
                                    removeIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.Clone:
                                    indexToClone = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.ShiftUp:
                                    moveUpIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.ShiftDown:
                                    moveDownIndex = j;
                                    break;
                                case DTGUIHelper.DTFunctionButtons.Play:
                                    StopPreviewer();
                                    switch (aSong.audLocation) {
                                        case MasterAudio.AudioLocation.Clip:
                                            GetPreviewer().PlayOneShot(aSong.clip, aSong.volume);
                                            break;
                                        case MasterAudio.AudioLocation.ResourceFile:
                                            GetPreviewer().PlayOneShot(Resources.Load(aSong.resourceFileName) as AudioClip, aSong.volume);
                                            break;
                                    }
                                    break;
                                case DTGUIHelper.DTFunctionButtons.Stop:
                                    GetPreviewer().clip = null;
                                    StopPreviewer();
                                    break;
                            }
                            EditorGUILayout.EndVertical();
                            DTGUIHelper.AddSpaceForNonU5(2);
                        }

                        if (addIndex.HasValue) {
                            var mus = new MusicSetting();
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "add song");
                            aList.MusicSettings.Insert(addIndex.Value + 1, mus);
                        } else if (removeIndex.HasValue) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "delete song");
                            aList.MusicSettings.RemoveAt(removeIndex.Value);
                        } else if (moveUpIndex.HasValue) {
                            var item = aList.MusicSettings[moveUpIndex.Value];

                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "shift up song");

                            aList.MusicSettings.Insert(moveUpIndex.Value - 1, item);
                            aList.MusicSettings.RemoveAt(moveUpIndex.Value + 1);
                        } else if (moveDownIndex.HasValue) {
                            var index = moveDownIndex.Value + 1;
                            var item = aList.MusicSettings[index];

                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "shift down song");

                            aList.MusicSettings.Insert(index - 1, item);
                            aList.MusicSettings.RemoveAt(index + 1);
                        } else if (indexToClone.HasValue) {
                            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "clone song");
                            aList.MusicSettings.Insert(indexToClone.Value, MusicSetting.Clone(aList.MusicSettings[indexToClone.Value]));
                        }
                    }

                    switch (playlistButtonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            playlistToRemove = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Add:
                            playlistToInsertAt = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.ShiftUp:
                            playlistToMoveUp = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.ShiftDown:
                            playlistToMoveDown = i;
                            break;
                    }

                    EditorGUILayout.EndVertical();
                    DTGUIHelper.AddSpaceForNonU5(4);
                }

                if (playlistToRemove.HasValue) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "delete Playlist");
                    _sounds.musicPlaylists.RemoveAt(playlistToRemove.Value);
                }
                if (playlistToInsertAt.HasValue) {
                    var pl = new MasterAudio.Playlist();
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "add Playlist");
                    _sounds.musicPlaylists.Insert(playlistToInsertAt.Value + 1, pl);
                }
                if (playlistToMoveUp.HasValue) {
                    var item = _sounds.musicPlaylists[playlistToMoveUp.Value];
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "shift up Playlist");
                    _sounds.musicPlaylists.Insert(playlistToMoveUp.Value - 1, item);
                    _sounds.musicPlaylists.RemoveAt(playlistToMoveUp.Value + 1);
                }
                if (playlistToMoveDown.HasValue) {
                    var index = playlistToMoveDown.Value + 1;
                    var item = _sounds.musicPlaylists[index];

                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "shift down Playlist");

                    _sounds.musicPlaylists.Insert(index - 1, item);
                    _sounds.musicPlaylists.RemoveAt(index + 1);
                }
            }

            if (addPressed) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "add Playlist");
                _sounds.musicPlaylists.Add(new MasterAudio.Playlist());
            }

            DTGUIHelper.EndGroupedControls();
        }
        // Music playlist End

        // Custom Events Start
        EditorGUI.indentLevel = 0;
        DTGUIHelper.VerticalSpace(3);

        DTGUIHelper.ResetColors();

        state = _sounds.showCustomEvents;
        text = "Custom Events";

        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
        if (!state) {
            GUI.backgroundColor = DTGUIHelper.InactiveHeaderColor;
        } else {
            GUI.backgroundColor = DTGUIHelper.ActiveHeaderColor;
        }

        GUILayout.BeginHorizontal();

#if UNITY_3_5_7
        if (!state) {
            text += " (Click to expand)";
        }
#else
        text = "<b><size=11>" + text + "</size></b>";
#endif
        if (state) {
            text = "\u25BC " + text;
        } else {
            text = "\u25BA " + text;
        }
        if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) {
            state = !state;
        }

        GUILayout.Space(2f);

        isExp = state;

        if (isExp != _sounds.showCustomEvents) {
            AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle Custom Events");
            _sounds.showCustomEvents = isExp;
        }
        DTGUIHelper.AddHelpIcon("https://dl.dropboxusercontent.com/u/40293802/DarkTonic/MA_OnlineDocs/CustomEvents.htm");

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

        if (_sounds.showCustomEvents) {
            DTGUIHelper.BeginGroupedControls();
            var newEvent = EditorGUILayout.TextField("New Event Name", _sounds.newEventName);
            if (newEvent != _sounds.newEventName) {
                AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change New Event Name");
                _sounds.newEventName = newEvent;
            }

            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(10);
            GUI.contentColor = DTGUIHelper.BrightButtonColor;
            if (GUILayout.Button("Create New Event", EditorStyles.toolbarButton, GUILayout.Width(100))) {
                CreateCustomEvent(_sounds.newEventName);
            }
            GUILayout.Space(10);
            GUI.contentColor = DTGUIHelper.BrightButtonColor;

            var hasExpanded = false;
            foreach (var t in _sounds.customEvents) {
                if (!t.eventExpanded) {
                    continue;
                }
                hasExpanded = true;
                break;
            }

            var buttonText = hasExpanded ? "Collapse All" : "Expand All";

            if (GUILayout.Button(buttonText, EditorStyles.toolbarButton, GUILayout.Width(100))) {
                ExpandCollapseCustomEvents(!hasExpanded);
            }
            GUILayout.Space(10);
            if (GUILayout.Button("Sort Alpha", EditorStyles.toolbarButton, GUILayout.Width(100))) {
                SortCustomEvents();
            }

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

            if (_sounds.customEvents.Count == 0) {
                DTGUIHelper.ShowLargeBarAlert("You currently have no Custom Events.");
            }

            int? customEventToDelete = null;
            int? eventToRename = null;

            for (var i = 0; i < _sounds.customEvents.Count; i++) {
                EditorGUI.indentLevel = 1;
                var anEvent = _sounds.customEvents[i];

                DTGUIHelper.AddSpaceForNonU5(2);
                DTGUIHelper.StartGroupHeader();

                EditorGUILayout.BeginHorizontal();
                var exp = DTGUIHelper.Foldout(anEvent.eventExpanded, anEvent.EventName);
                if (exp != anEvent.eventExpanded) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "toggle expand Custom Event");
                    anEvent.eventExpanded = exp;
                }

                GUILayout.FlexibleSpace();
                if (Application.isPlaying) {
                    var receivers = MasterAudio.ReceiversForEvent(anEvent.EventName);

                    GUI.contentColor = DTGUIHelper.BrightButtonColor;
                    if (receivers.Count > 0) {
                        if (GUILayout.Button(new GUIContent("Select", "Click this button to select all Receivers in the Hierarchy"), EditorStyles.toolbarButton, GUILayout.Width(50))) {
                            var matches = new List<GameObject>(receivers.Count);

                            foreach (var t in receivers) {
                                matches.Add(t.gameObject);
                            }
                            Selection.objects = matches.ToArray();
                        }
                    }

                    if (GUILayout.Button("Fire!", EditorStyles.toolbarButton, GUILayout.Width(50))) {
                        MasterAudio.FireCustomEvent(anEvent.EventName, _sounds.transform.position);
                    }

                    GUI.contentColor = DTGUIHelper.BrightButtonColor;
                    GUILayout.Label(string.Format("Receivers: {0}", receivers.Count));
                    GUI.contentColor = Color.white;
                } else {
                    var newName = GUILayout.TextField(anEvent.ProspectiveName, GUILayout.Width(170));
                    if (newName != anEvent.ProspectiveName) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Proposed Event Name");
                        anEvent.ProspectiveName = newName;
                    }

                    var buttonPressed = DTGUIHelper.AddDeleteIcon(true, "Custom Event");

                    switch (buttonPressed) {
                        case DTGUIHelper.DTFunctionButtons.Remove:
                            customEventToDelete = i;
                            break;
                        case DTGUIHelper.DTFunctionButtons.Rename:
                            eventToRename = i;
                            break;
                    }
                }

                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndVertical();

                if (!anEvent.eventExpanded) {
                    EditorGUILayout.EndVertical();
                    continue;
                }

                EditorGUI.indentLevel = 0;
                var rcvMode = (MasterAudio.CustomEventReceiveMode)EditorGUILayout.EnumPopup("Send To Receivers", anEvent.eventReceiveMode);
                if (rcvMode != anEvent.eventReceiveMode) {
                    AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Send To Receivers");
                    anEvent.eventReceiveMode = rcvMode;
                }

                if (rcvMode == MasterAudio.CustomEventReceiveMode.WhenDistanceLessThan || rcvMode == MasterAudio.CustomEventReceiveMode.WhenDistanceMoreThan) {
                    var newDist = EditorGUILayout.Slider("Distance Threshold", anEvent.distanceThreshold, 0f, float.MaxValue);
                    if (newDist != anEvent.distanceThreshold) {
                        AudioUndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _sounds, "change Distance Threshold");
                        anEvent.distanceThreshold = newDist;
                    }
                }
                EditorGUILayout.EndVertical();
            }

            if (customEventToDelete.HasValue) {
                _sounds.customEvents.RemoveAt(customEventToDelete.Value);
            }
            if (eventToRename.HasValue) {
                RenameEvent(_sounds.customEvents[eventToRename.Value]);
            }

            DTGUIHelper.EndGroupedControls();
        }

        // Custom Events End

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

        //DrawDefaultInspector();
    }
Exemplo n.º 29
0
    void LoadJson(string fileName)
    {
        var          textAsset = Resources.Load(fileName) as TextAsset;
        var          jsonText  = textAsset.text;
        MusicSetting item      = JsonUtility.FromJson <MusicSetting>(jsonText);

        List <Timing>[] timingList = new List <Timing> [item.maxBlock];
        //List<LongNoteTiming>[] longNoteTimingList = new List<LongNoteTiming>[item.maxBlock-3];
        List <Timing>[] longNoteStartTimingList = new List <Timing> [item.maxBlock - 3];
        List <Timing>[] longNoteEndTimingList   = new List <Timing> [item.maxBlock - 3];
        List <float>[]  longActiveTimeList      = new List <float> [item.maxBlock - 3];
        longFlags = new bool[item.maxBlock - 3];
        for (int i = 0; i < timingList.Length; i++)
        {
            //リストのリストになっている
            timingList [i] = new List <Timing> ();
        }
        for (int i = 0; i < longNoteStartTimingList.Length; i++)
        {
            longNoteStartTimingList[i] = new List <Timing>();
        }
        for (int i = 0; i < longNoteEndTimingList.Length; i++)
        {
            longNoteEndTimingList[i] = new List <Timing>();
        }
        for (int i = 0; i < longActiveTimeList.Length; i++)
        {
            longActiveTimeList[i] = new List <float>();
        }
        foreach (NoteInformation note in item.notes)
        {
            int type = note.type;
            if (type == 1)
            {
                Timing tmp = LoadTiming(note.num + 64);
                timingList [note.block].Add(tmp);
            }
            else if (type == 2)
            {
                foreach (NoteInformation longNote in note.notes)
                {
                    LongNoteTiming tmp = new LongNoteTiming();
                    tmp.startTiming = LoadTiming(note.num + 64);
                    tmp.endTiming   = LoadTiming(longNote.num + 64);

                    longNoteStartTimingList [note.block].Add(tmp.startTiming);
                    longNoteEndTimingList [note.block].Add(tmp.endTiming);
                    float longTiming = longNote.num - note.num;
                    float longTime   = (longTiming * 2 / 25) * 1.31f;
                    // Debug.Log(longTime);
                    longActiveTimeList[note.block].Add(longTime);
                }
            }
        }

        for (int i = 0; i < noteLane.Length; i++)
        {
            /*余分にタイミングを足すことでおかしな終了をしないようにする
             * 0,0,0は決して最後にならないので良い*/
            timingList [i].Add(new Timing(0, 0, 0));
            noteLane [i].timings          = timingList [i].ToArray();    //timingListをリストから配列に変換し、各レーンのタイミングデータにする.
            noteLane[i].highSpeedLevel    = highSpeedLevel;
            noteLane [i].updateStartPoint = startPoint;
        }

        for (int i = 0; i < longNoteLane.Length; i++)
        {
            longNoteStartTimingList [i].Add(new Timing(0, 0, 0));
            longNoteLane [i].startTimings = longNoteStartTimingList [i].ToArray();
            longNoteEndTimingList [i].Add(new Timing(0, 0, 0));
            longNoteLane [i].endTimings       = longNoteEndTimingList [i].ToArray();
            longNoteLane[i].longActiveTimes   = longActiveTimeList[i].ToArray();
            longNoteLane[i].highSpeedLevel    = highSpeedLevel;
            longNoteLane [i].updateStartPoint = startPoint;
            longNoteLane[i].longLaneNum       = i;
        }
    }
Exemplo n.º 30
0
    private void PlaySong(MusicSetting setting)
    {
        newSongSetting = setting;

        if (activeAudio == null) {
            Debug.LogError("PlaylistController prefab is not in your scene. Cannot play a song.");
            return;
        }

        if (activeAudio.clip != null) {
            var newSongName = string.Empty;
            switch (setting.audLocation) {
                case MasterAudio.AudioLocation.Clip:
                    if (setting.clip != null) {
                        newSongName = setting.clip.name;
                    }
                    break;
                case MasterAudio.AudioLocation.ResourceFile:
                    newSongName = setting.resourceFileName;
                    break;
            }

            if (string.IsNullOrEmpty(newSongName)) {
                Debug.LogWarning("The next song has no clip or Resource file assigned. Please fix this. Ignoring song change request.");
                return;
            }
        }

        if (activeAudio.clip == null) {
            audioClip = activeAudio;
            transClip = transitioningAudio;
        } else if (transitioningAudio.clip == null) {
            audioClip = transitioningAudio;
            transClip = activeAudio;
        } else {
            // both are busy!
            audioClip = transitioningAudio;
            transClip = activeAudio;
        }

        if (setting.clip != null) {
            audioClip.clip = setting.clip;
            audioClip.pitch = setting.pitch;
        }

        audioClip.loop = SongShouldLoop(setting);

        AudioClip clipToPlay = null;

        switch (setting.audLocation) {
            case MasterAudio.AudioLocation.Clip:
                if (setting.clip == null) {
                    MasterAudio.LogWarning("MasterAudio will not play empty Playlist clip for PlaylistController '" + this.ControllerName + "'.");
                    return;
                }

                clipToPlay = setting.clip;
                break;
            case MasterAudio.AudioLocation.ResourceFile:
                if (MasterAudio.HasAsyncResourceLoaderFeature() && ShouldLoadAsync) {
                    StartCoroutine(AudioResourceOptimizer.PopulateResourceSongToPlaylistControllerAsync(setting.resourceFileName, this.CurrentPlaylist.playlistName, this));
                } else {
                    clipToPlay = AudioResourceOptimizer.PopulateResourceSongToPlaylistController(ControllerName, setting.resourceFileName, this.CurrentPlaylist.playlistName);
                    if (clipToPlay == null) {
                        return;
                    }
                }

                break;
        }

        if (clipToPlay != null) {
            FinishLoadingNewSong(clipToPlay);
        }
    }