public void AddThemes(params AreaTheme[] themes) { _themes.Clear(); _alreadyPlayingThemes.Clear(); ActiveTheme = null; foreach (var theme in themes) { #if UNITY_EDITOR if (theme == null || !theme.AmbientSound.IsNotEmpty()) { Debug.LogError("AddTheme caused: theme is null or empty"); return; } if (_themes.Any(t => t.Name == theme.Name)) { Debug.LogError("AddTheme caused: Theme with name " + theme.Name + " already exists"); return; } #endif _themes.Add(theme); } }
private IEnumerator ActivateTheme(string themeName) { yield return(null); // If null then fade all themes if (string.IsNullOrEmpty(themeName)) { ActiveTheme = null; yield break; } AreaTheme theme = _themes.FirstOrDefault(t => t.Name == themeName); // If there is no such theme - do nothing if (theme == null) { yield break; } // If this theme is already active - do nothing if (ActiveTheme != null && theme.Name == ActiveTheme.Name) { yield break; } // Make this theme active ActiveTheme = theme; // If theme is already playing - do nothing if (!_alreadyPlayingThemes.Add(theme)) { yield break; } // Sarting theme playing AudioClip clip = GetClipFromSound(theme.AmbientSound); var listener = FindObjectOfType <AudioListener>().transform; AudioSource source = GetAudioSource(listener, listener.position); source.clip = clip; source.loop = true; source.volume = 0; source.Play(); Dictionary <RandomSound, float> randomSoundDelays = theme.RandomSounds .Where(r => r.Sound.IsNotEmpty()) .ToDictionary(k => k, v => Random.Range(5f, v.MaxSecondsDelay)); float activeRaito = theme.Name == ActiveTheme.Name ? 1 : 0; // Store all currently playing theme sounds to be able change their volume var activeAudioSources = new HashSet <AudioSource>(new[] { source }); while (true) { yield return(null); bool isActive = ActiveTheme.Name == theme.Name; activeRaito = Mathf.Lerp(activeRaito, isActive ? 1 : 0, Time.deltaTime * ThemeFadeFactor); float actualVolume = theme.BaseVolume * activeRaito * CurrentAmbientVolume; // Remove all sounds that are already finished playing activeAudioSources.RemoveWhere(a => a != source && !a.isPlaying); // Change all sounds volume depending to the actual one foreach (AudioSource audioSource in activeAudioSources) { audioSource.volume = actualVolume; } // Play random sounds foreach (RandomSound sound in randomSoundDelays.Keys.ToArray()) { randomSoundDelays[sound] -= Time.deltaTime; if (randomSoundDelays[sound] <= 0) { AudioSource audioSource = Play(sound.Sound, actualVolume); // Store sound source for later use activeAudioSources.Add(audioSource); randomSoundDelays[sound] = Random.Range(sound.MinSecondsDelay, sound.MaxSecondsDelay); } } } }