void Awake() { if (_mixerControls != null) { for (int i = 0; i < _mixerControls.Length; ++i) { var c = _mixerControls[i]; if (c.mixerGroup != null) { MixerGroupState s = new MixerGroupState(); s.mixerControl = c; _mixerState.Add(c.mixerGroup, s); } } } }
bool CanPlay(Actor actor, GameObject go, SoundCue sound, double time, out MixerGroupState groupState, out PlayingSource playingSource) { groupState = null; playingSource = null; if (sound.audioSourcePrefab.outputAudioMixerGroup != null) { if (_mixerState.TryGetValue(sound.audioSourcePrefab.outputAudioMixerGroup, out groupState)) { if (groupState.hasPlayed && (groupState.mixerControl.maxGroupRate > 0f)) { double d = time - groupState.lastTime; if (d < groupState.mixerControl.maxGroupRate) { return(false); } } if (go != null) { if (!groupState.playingSources.TryGetValue(go, out playingSource)) { playingSource = new PlayingSource(); playingSource.go = go; playingSource.actor = actor; groupState.playingSources.Add(go, playingSource); } } else { playingSource = groupState.positionalSource; } if (playingSource.hasPlayed && (groupState.mixerControl.maxSourceRate > 0f)) { double d = time - playingSource.lastTime; if (d < groupState.mixerControl.maxSourceRate) { return(false); } } if (groupState.mixerControl.maxGroupVoices > 0) { if (groupState.currentVoiceCount >= groupState.mixerControl.maxGroupVoices) { var stopSource = groupState.activeSources[0]; bool shouldStop = true; if (groupState.mixerControl.groupLimit == ELimitMode.Discard) { bool discard = true; if (groupState.mixerControl.maxSourceVoices > 0) { if (playingSource.sources.Count >= groupState.mixerControl.maxSourceVoices) { if (groupState.mixerControl.sourceLimit != ELimitMode.Discard) { if (playingSource != stopSource.playingSource) { // the group limit has been reached and the source // will not stop it. return(false); } // the source voice limit will force a sound on the group to stop from // this source, satisfying the group limit discard = false; shouldStop = false; } } } if (discard) { return(false); } } if (shouldStop) { // stop the oldest playing voice... if (groupState.mixerControl.maxSourceVoices > 0) { if (playingSource.sources.Count >= groupState.mixerControl.maxSourceVoices) { if (groupState.mixerControl.sourceLimit == ELimitMode.Discard) { if (playingSource != stopSource.playingSource) { // the source limit has been reached, even if we stopped this voice // it won't play so don't stop it. return(false); } } // the source voice limit will force a sound on the group to stop from // this source, satisfying the group limit shouldStop = false; } } } if (shouldStop) { if (stopSource.audioSource != null) { Utils.DestroyGameObject(stopSource.audioSource.gameObject); } stopSource.playingSource.sources.Remove(stopSource); groupState.activeSources.RemoveAt(0); --groupState.currentVoiceCount; } } } if (groupState.mixerControl.maxSourceVoices > 0) { if (playingSource.sources.Count >= groupState.mixerControl.maxSourceVoices) { if (groupState.mixerControl.sourceLimit == ELimitMode.Discard) { return(false); } var stopSource = playingSource.sources[0]; if (stopSource.audioSource != null) { Utils.DestroyGameObject(stopSource.audioSource.gameObject); } groupState.activeSources.Remove(stopSource); playingSource.sources.RemoveAt(0); --groupState.currentVoiceCount; } } } } return(true); }