Beispiel #1
0
    private static PlaySoundResult PlaySoundIfAvailable(string soundGroupName,
            AudioInfo info,
            Vector3 sourcePosition,
            float volumePercentage,
            ref bool forgetSoundPlayed,
            float? pitch = null,
            AudioGroupInfo audioGroup = null,
            Transform sourceTrans = null,
            bool attachToSource = false,
            float delaySoundTime = 0f,
            bool useVector3 = false,
            bool makePlaySoundResult = false,
			bool isChaining = false,
			bool isSingleSubscribedPlay = false)
    {
        if (info.source == null)
        {
            // this avoids false errors when stopping the game (from became "invisible" event callers)
            return null;
        }

        MasterAudioGroup maGroup = audioGroup._group;

        if (maGroup.curVariationMode == MasterAudioGroup.VariationMode.Normal && info.source.audio.isPlaying)
        {
            var playedPercentage = AudioUtil.GetAudioPlayedPercentage(info.source);
            var retriggerPercent = maGroup.retriggerPercentage;

            if (playedPercentage < retriggerPercent)
            {
                return null; // wait for this to stop playing or play further.
            }
        }

        info.variation.Stop();
        info.variation.ObjectToFollow = null;

        if (useVector3)
        {
            info.source.transform.position = sourcePosition;
            if (MasterAudio.Instance.prioritizeOnDistance)
            {
                AudioPrioritizer.Set3dPriority(info.source);
            }
        }
        else if (sourceTrans != null)
        {
            if (attachToSource)
            {
                info.variation.ObjectToFollow = sourceTrans;
            }
            else
            {
                info.source.transform.position = sourceTrans.position;
                info.variation.ObjectToTriggerFrom = sourceTrans;
            }

            if (MasterAudio.Instance.prioritizeOnDistance)
            {
                AudioPrioritizer.Set3dPriority(info.source);
            }
        }
        else
        {
            // "2d manner" - from Master Audio location
            if (MasterAudio.Instance.prioritizeOnDistance)
            {
                AudioPrioritizer.Set2dSoundPriority(info.source);
            }
            info.source.transform.localPosition = Vector3.zero; // put it back in MA prefab position after being detached.
        }

        var groupVolume = maGroup.groupMasterVolume;
        var busVolume = GetBusVolume(maGroup);

        float calcVolume = info.originalVolume * groupVolume * busVolume * MasterAudio.Instance.masterAudioVolume;

        // set volume to percentage.
        float volume = calcVolume * volumePercentage;
        var targetVolume = volume;

        var randomVol = 0f;
        if (info.variation.useRandomVolume) {
            // random volume
            randomVol = UnityEngine.Random.Range(info.variation.randomVolumeMin, info.variation.randomVolumeMax);

            switch (info.variation.randomVolumeMode) {
                case SoundGroupVariation.RandomVolumeMode.AddToClipVolume:
                    targetVolume += randomVol;
                    break;
                case SoundGroupVariation.RandomVolumeMode.IgnoreClipVolume:
                    targetVolume = randomVol;
                    break;
            }
        }

        info.source.audio.volume = targetVolume;

        // save these for on the fly adjustments afterward
        info.lastPercentageVolume = volumePercentage;
        info.lastRandomVolume = randomVol;

        bool isActive = false;

        #if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
        isActive = info.source.audio.gameObject.active;
        #else
            isActive = info.source.audio.gameObject.activeInHierarchy;
        #endif

        if (!isActive)
        {
            return null;
        }

        PlaySoundResult result = null;

        if (makePlaySoundResult)
        {
            result = new PlaySoundResult();
            result.ActingVariation = info.variation;

            if (delaySoundTime > 0f)
            {
                result.SoundScheduled = true;
            }
            else
            {
                result.SoundPlayed = true;
            }
        }
        else
        {
            forgetSoundPlayed = true;
        }

        var playSoundParams = new SoundGroupVariation.PlaySoundParams(maGroup.name,
              volumePercentage,
              targetVolume,
              pitch,
              sourceTrans,
              attachToSource,
              delaySoundTime,
              maGroup.curVariationMode == MasterAudioGroup.VariationMode.LoopedChain,
              isSingleSubscribedPlay);

        if (playSoundParams.isChainLoop && !isChaining) {
            maGroup.ChainLoopCount = 0;
        }

        if (playSoundParams.isChainLoop)
        {
            // make sure there isn't 2 going, ever
            MasterAudio.StopAllOfSound(playSoundParams.soundType);
        }

        info.variation.Play(pitch, targetVolume, playSoundParams);

        return result;
    }
Beispiel #2
0
    void Awake()
    {
        if (GameObject.FindObjectsOfType(typeof(MasterAudio)).Length > 1) {
            Destroy(gameObject);
            Debug.Log("More than one Master Audio prefab exists in this Scene. Destroying the newer one called '" + this.name + "'. You may wish to set up a Bootstrapper Scene so this does not occur.");
            return;
        }

        this.useGUILayout = false;
        trans = this.transform;
        soundsLoaded = false;

        var aud = this.audio;
        if (aud != null)
        {
            // delete the previewer
            GameObject.Destroy(aud);
        }

        audioSourcesBySoundType.Clear();
        playlistControllersByName.Clear();
        lastTimeSoundGroupPlayed.Clear();

        var plNames = new List<string>();
        AudioResourceOptimizer.ClearAudioClips();

        PlaylistController.Instances = null; // clear the cache
        var playlists = PlaylistController.Instances;
        for (var i = 0; i < playlists.Count; i++)
        {
            var aList = playlists[i];

            if (plNames.Contains(aList.name))
            {
                Debug.LogError("You have more than 1 Playlist Controller with the name '" + aList.name + "'. You must name them all uniquely or the same-named ones will be deleted once they awake.");
                continue;
            }
            else
            {
                plNames.Add(aList.name);
            }

            playlistControllersByName.Add(aList.name, aList);
            if (persistBetweenScenes)
            {
                DontDestroyOnLoad(aList);
            }
        }

        // start up Objects!
        if (persistBetweenScenes)
        {
            DontDestroyOnLoad(this.gameObject);
        }

        Transform parentGroup;
        List<AudioInfo> sources;

        var playedStatuses = new List<int>();
        AudioSource source;
        AudioGroupInfo _group;
        MasterAudioGroup groupScript;
        randomizer = new Dictionary<string, List<int>>();
        clipsPlayedBySoundTypeOldestFirst = new Dictionary<string, List<int>>();
        string soundType = string.Empty;

        var firstGroupName = string.Empty;

        for (var k = 0; k < trans.childCount; k++)
        {
            parentGroup = trans.GetChild(k);

            sources = new List<AudioInfo>();

            groupScript = parentGroup.GetComponent<MasterAudioGroup>();

            if (groupScript == null)
            {
                Debug.LogError("MasterAudio could not find 'MasterAudioGroup' script for group '" + parentGroup.name + "'. Skipping this group.");
                continue;
            }

            soundType = parentGroup.name;

            if (string.IsNullOrEmpty(firstGroupName)) {
                firstGroupName = soundType;
            }

            var newWeightedChildren = new List<Transform>();

            SoundGroupVariation variation = null;
            SoundGroupVariation childVariation = null;
            Transform child = null;

            for (int i = 0; i < parentGroup.childCount; i++)
            {
                child = parentGroup.GetChild(i);
                variation = child.GetComponent<SoundGroupVariation>();
                source = child.audio;

                var weight = variation.weight;

                for (var j = 0; j < weight; j++)
                {
                    if (j > 0)
                    {
                        var extraChild = (GameObject)GameObject.Instantiate(child.gameObject, parentGroup.transform.position, Quaternion.identity);
                        extraChild.transform.name = child.gameObject.name;
                        childVariation = extraChild.GetComponent<SoundGroupVariation>();
                        childVariation.weight = 1;

                        newWeightedChildren.Add(extraChild.transform);
                        source = extraChild.audio;

                        sources.Add(new AudioInfo(childVariation, source, source.volume));

                        if (childVariation.audLocation == MasterAudio.AudioLocation.ResourceFile)
                        {
                            AudioResourceOptimizer.AddTargetForClip(childVariation.resourceFileName, source);
                        }
                    }
                    else
                    {
                        sources.Add(new AudioInfo(variation, source, source.volume));

                        if (variation.audLocation == MasterAudio.AudioLocation.ResourceFile)
                        {
                            AudioResourceOptimizer.AddTargetForClip(variation.resourceFileName, source);
                        }
                    }
                }
            }

            // attach extra children from weight property.
            for (var i = 0; i < newWeightedChildren.Count; i++)
            {
                newWeightedChildren[i].parent = parentGroup;
            }

            _group = new AudioGroupInfo(sources, groupScript);
            if (groupScript.isSoloed)
            {
                soloedGroups.Add(groupScript);
            }

            if (audioSourcesBySoundType.ContainsKey(soundType))
            {
                Debug.LogError("You have more than one SoundGroup named '" + soundType + "'. Ignoring the 2nd one. Please rename it.");
                continue;
            }

            _group._sources.Sort(delegate(AudioInfo x, AudioInfo y)
            {
                return x.variation.name.CompareTo(y.variation.name);
            });

            audioSourcesBySoundType.Add(soundType, _group);

            for (var i = 0; i < sources.Count; i++)
            {
                playedStatuses.Add(i);
            }

            randomizer.Add(soundType, playedStatuses);
            clipsPlayedBySoundTypeOldestFirst.Add(soundType, new List<int>());

            playedStatuses = new List<int>();
        }

        busFades.Clear();
        groupFades.Clear();

        Playlist pl = null;
        float firstSongLength = 0f;

        // check Syncrhonized Playlists for problems!
        for (var i = 0; i < musicPlaylists.Count; i++)
        {
            pl = musicPlaylists[i];
            if (pl.songTransitionType != SongFadeInPosition.SynchronizeClips)
            {
                continue;
            }

            if (pl.MusicSettings.Count < 2)
            {
                continue;
            }

            var songOne = pl.MusicSettings[0].clip;
            if (songOne == null)
            {
                continue;
            }

            firstSongLength = songOne.length;
            for (var s = 1; s < pl.MusicSettings.Count; s++)
            {
                var clip = pl.MusicSettings[s].clip;
                if (clip == null)
                {
                    continue;
                }

                if (clip.length != firstSongLength)
                {
                    Debug.LogError("Playlist '" + pl.playlistName + "' is marked as Synchronized but the clip lengths are not all the same within the Playlist. Clips may not synchronize as intended.");
                    break;
                }
            }
        }

        // populate ducking sounds dictionary
        duckingBySoundType.Clear();
        for (var i = 0; i < musicDuckingSounds.Count; i++)
        {
            var aDuck = musicDuckingSounds[i];
            duckingBySoundType.Add(aDuck.soundType, aDuck);
        }

        soundsLoaded = true;

        // pre-warm the code so the first sound played for real doesn't have to JIT and be slow.
        if (!string.IsNullOrEmpty(firstGroupName)) {
            var result = PlaySound(firstGroupName, 0f, 1f, 0f, null, false, false);
            if (result != null && result.SoundPlayed) {
                result.ActingVariation.Stop();
            }
        }
    }
        private static void AddRuntimeGroupInfo(string groupName, AudioGroupInfo groupInfo) {
            AudioSourcesBySoundType.Add(groupName, groupInfo);

            var sources = new List<AudioSource>(groupInfo.Sources.Count);
            // ReSharper disable ForCanBeConvertedToForeach
            for (var i = 0; i < groupInfo.Sources.Count; i++) {
                // ReSharper restore ForCanBeConvertedToForeach
                sources.Add(groupInfo.Sources[i].Source);
            }

            TrackRuntimeAudioSources(sources);
        }
        /*! \endcond */
        #endregion

        #region MonoDevelop events and Helpers

        // ReSharper disable once UnusedMember.Local
        // ReSharper disable once FunctionComplexityOverflow
        private void Awake() {
            if (FindObjectsOfType(typeof(MasterAudio)).Length > 1) {
                Destroy(gameObject);
                Debug.Log("More than one Master Audio prefab exists in this Scene. Destroying the newer one called '" +
                          name + "'. You may wish to set up a Bootstrapper Scene so this does not occur.");
                return;
            }

            useGUILayout = false;
            _soundsLoaded = false;

            _innerLoopDelay = new WaitForSeconds(InnerLoopCheckInterval);

            var aud = GetComponent<AudioSource>();
            if (aud != null) {
                // delete the previewer
                // ReSharper disable once ArrangeStaticMemberQualifier
                GameObject.Destroy(aud);
            }

            AudioSourcesBySoundType.Clear();
            PlaylistControllersByName.Clear();
            LastTimeSoundGroupPlayed.Clear();

            var plNames = new List<string>();
            AudioResourceOptimizer.ClearAudioClips();

            PlaylistController.Instances = null; // clear the cache
            var playlists = PlaylistController.Instances;
            // ReSharper disable once ForCanBeConvertedToForeach
            for (var i = 0; i < playlists.Count; i++) {
                var aList = playlists[i];

                if (plNames.Contains(aList.name)) {
                    Debug.LogError("You have more than 1 Playlist Controller with the name '" + aList.name +
                                   "'. You must name them all uniquely or the same-named ones will be deleted once they awake.");
                    continue;
                }

                plNames.Add(aList.name);

                PlaylistControllersByName.Add(aList.name, aList);
                if (persistBetweenScenes) {
                    DontDestroyOnLoad(aList);
                }
            }

            // start up Objects!
            if (persistBetweenScenes) {
                DontDestroyOnLoad(gameObject);
            }

            var playedStatuses = new List<int>();

            // ReSharper disable TooWideLocalVariableScope
            Transform parentGroup;
            List<AudioInfo> sources;
            AudioSource source;
            AudioGroupInfo group;
            MasterAudioGroup groupScript;
            string soundType;
            // ReSharper restore TooWideLocalVariableScope

            _randomizer = new Dictionary<string, List<int>>();
            _randomizerLeftovers = new Dictionary<string, List<int>>();
            _clipsPlayedBySoundTypeOldestFirst = new Dictionary<string, List<int>>();

            var firstGroupName = string.Empty;

            var allVars = new List<SoundGroupVariation>();

            _groupsToRemove = new List<string>(Trans.childCount);

            for (var k = 0; k < Trans.childCount; k++) {
                parentGroup = Trans.GetChild(k);

                sources = new List<AudioInfo>();

                groupScript = parentGroup.GetComponent<MasterAudioGroup>();

                if (groupScript == null) {
                    Debug.LogError("MasterAudio could not find 'MasterAudioGroup' script for group '" + parentGroup.name +
                                   "'. Skipping this group.");
                    continue;
                }

                soundType = parentGroup.name;

                if (string.IsNullOrEmpty(firstGroupName)) {
                    firstGroupName = soundType;
                }

                var newWeightedChildren = new List<Transform>();

                // ReSharper disable TooWideLocalVariableScope
                SoundGroupVariation variation;
                SoundGroupVariation childVariation;
                Transform child;
                // ReSharper restore TooWideLocalVariableScope

                for (var i = 0; i < parentGroup.childCount; i++) {
                    child = parentGroup.GetChild(i);
                    variation = child.GetComponent<SoundGroupVariation>();
                    source = child.GetComponent<AudioSource>();

                    var weight = variation.weight;

                    for (var j = 0; j < weight; j++) {
                        if (j > 0) {
                            // ReSharper disable once ArrangeStaticMemberQualifier
                            var extraChild =
                                (GameObject)
                                    GameObject.Instantiate(child.gameObject, parentGroup.transform.position,
                                        Quaternion.identity);
                            extraChild.transform.name = child.gameObject.name;
                            childVariation = extraChild.GetComponent<SoundGroupVariation>();
                            childVariation.weight = 1;

                            newWeightedChildren.Add(extraChild.transform);
                            source = extraChild.GetComponent<AudioSource>();

                            sources.Add(new AudioInfo(childVariation, source, source.volume));
                            allVars.Add(childVariation);

                            switch (childVariation.audLocation) {
                                case AudioLocation.ResourceFile:
                                    AudioResourceOptimizer.AddTargetForClip(childVariation.resourceFileName, source);
                                    break;
                                case AudioLocation.FileOnInternet:
                                    AudioResourceOptimizer.AddTargetForClip(childVariation.internetFileUrl, source);
                                    break;
                            }
                        } else {
                            sources.Add(new AudioInfo(variation, source, source.volume));
                            allVars.Add(variation);

                            switch (variation.audLocation) {
                                case AudioLocation.ResourceFile:
                                    var resFileName =
                                        AudioResourceOptimizer.GetLocalizedFileName(variation.useLocalization,
                                            variation.resourceFileName);
                                    AudioResourceOptimizer.AddTargetForClip(resFileName, source);
                                    break;
                                case AudioLocation.FileOnInternet:
                                    AudioResourceOptimizer.AddTargetForClip(variation.internetFileUrl, source);
                                    break;
                            }
                        }
                    }
                }

                // attach extra children from weight property.
                // ReSharper disable once ForCanBeConvertedToForeach
                for (var i = 0; i < newWeightedChildren.Count; i++) {
                    newWeightedChildren[i].parent = parentGroup;
                }

                group = new AudioGroupInfo(sources, groupScript);
                if (groupScript.isSoloed) {
                    SoloedGroups.Add(groupScript);
                }

                if (AudioSourcesBySoundType.ContainsKey(soundType)) {
                    Debug.LogError("You have more than one SoundGroup named '" + soundType +
                                   "'. Ignoring the 2nd one. Please rename it.");
                    continue;
                }

                group.Group.OriginalVolume = group.Group.groupMasterVolume;
                // added code for persistent group volume
                var persistentVolume = PersistentAudioSettings.GetGroupVolume(soundType);
                if (persistentVolume.HasValue) {
                    group.Group.groupMasterVolume = persistentVolume.Value;
                }

                AddRuntimeGroupInfo(soundType, group);

                for (var i = 0; i < sources.Count; i++) {
                    playedStatuses.Add(i);
                }

                if (group.Group.curVariationSequence == MasterAudioGroup.VariationSequence.Randomized) {
                    ArrayListUtil.SortIntArray(ref playedStatuses);
                }

                _randomizer.Add(soundType, playedStatuses);
                _randomizerLeftovers.Add(soundType, new List<int>(playedStatuses.Count));
                // fill leftovers pool.
                _randomizerLeftovers[soundType].AddRange(playedStatuses);
                _clipsPlayedBySoundTypeOldestFirst.Add(soundType, new List<int>());

                playedStatuses = new List<int>();
            }

            BusFades.Clear();
            GroupFades.Clear();

            // ReSharper disable TooWideLocalVariableScope
            Playlist pl;
            float firstSongLength;
            // ReSharper restore TooWideLocalVariableScope

            // check Syncrhonized Playlists for problems!
            // ReSharper disable once ForCanBeConvertedToForeach
            for (var i = 0; i < musicPlaylists.Count; i++) {
                pl = musicPlaylists[i];
                if (pl.songTransitionType != SongFadeInPosition.SynchronizeClips) {
                    continue;
                }

                if (pl.MusicSettings.Count < 2) {
                    continue;
                }

                var songOne = pl.MusicSettings[0].clip;
                if (songOne == null) {
                    continue;
                }

                firstSongLength = songOne.length;
                for (var s = 1; s < pl.MusicSettings.Count; s++) {
                    var clip = pl.MusicSettings[s].clip;
                    if (clip == null) {
                        continue;
                    }

                    if (clip.length == firstSongLength) {
                        continue;
                    }
                    Debug.LogWarning("Playlist '" + pl.playlistName +
                                     "' is marked as Synchronized but the clip lengths are not all the same within the Playlist. Clips may not synchronize as intended.");
                    break;
                }
            }

            // initialize persistent bus volumes 
            // ReSharper disable once ForCanBeConvertedToForeach
            for (var i = 0; i < groupBuses.Count; i++) {
                var aBus = groupBuses[i];

                aBus.OriginalVolume = aBus.volume;
                var busName = aBus.busName;
                var busVol = PersistentAudioSettings.GetBusVolume(busName);

                if (!busVol.HasValue) {
                    continue;
                }

                SetBusVolumeByName(busName, busVol.Value);
            }

            // populate ducking sounds dictionary
            duckingBySoundType.Clear();
            // ReSharper disable once ForCanBeConvertedToForeach
            for (var i = 0; i < musicDuckingSounds.Count; i++) {
                var aDuck = musicDuckingSounds[i];
                if (duckingBySoundType.ContainsKey(aDuck.soundType)) {
                    continue;
                }
                duckingBySoundType.Add(aDuck.soundType, aDuck);
            }

            _soundsLoaded = true;

            _warming = true;

            // pre-warm the code so the first sound played for real doesn't have to JIT and be slow.
            if (!string.IsNullOrEmpty(firstGroupName)) {
                var result = PlaySound3DFollowTransform(firstGroupName, Trans, 0f);
                if (result != null && result.SoundPlayed) {
                    result.ActingVariation.Stop();
                }
            }

            FireCustomEvent("FakeEvent", _trans.position);

            // ReSharper disable once ForCanBeConvertedToForeach
            // Reset stuff for people who use "Save runtime changes".
            for (var i = 0; i < customEvents.Count; i++) {
                customEvents[i].frameLastFired = -1;
            }
            frames = 0;

            // Event Sounds warmer
            // ReSharper disable once ArrangeStaticMemberQualifier
            var evts = GameObject.FindObjectsOfType(typeof(EventSounds));
            if (evts.Length > 0) {
                var evt = evts[0] as EventSounds;
                evt.PlaySounds(evt.particleCollisionSound, EventSounds.EventType.UserDefinedEvent);
            }

            // done warming
            _warming = false;

            // ReSharper disable once ForCanBeConvertedToForeach
            for (var i = 0; i < allVars.Count; i++) {
                allVars[i].DisableUpdater();
            }

            // fixed: make sure this happens before Playlists start or the volume won't be right.
            PersistentAudioSettings.RestoreMasterSettings();
        }
        // ReSharper disable once FunctionComplexityOverflow
        private static PlaySoundResult PlaySoundIfAvailable(AudioInfo info,
            Vector3 sourcePosition,
            float volumePercentage,
            ref bool forgetSoundPlayed,
            float? pitch = null,
            AudioGroupInfo audioGroup = null,
            Transform sourceTrans = null,
            bool attachToSource = false,
            float delaySoundTime = 0f,
            bool useVector3 = false,
            bool makePlaySoundResult = false,
            bool isChaining = false,
            bool isSingleSubscribedPlay = false) {

            if (info.Source == null) {
                // this avoids false errors when stopping the game (from became "invisible" event callers)
                return null;
            }

            // ReSharper disable once PossibleNullReferenceException
            var maGroup = audioGroup.Group;

            if (maGroup.curVariationMode == MasterAudioGroup.VariationMode.Normal && info.Source.isPlaying) {
                var playedPercentage = AudioUtil.GetAudioPlayedPercentage(info.Source);
                var retriggerPercent = maGroup.retriggerPercentage;

                if (playedPercentage < retriggerPercent) {
                    return null; // wait for this to stop playing or play further.
                }
            }

            info.Variation.Stop();
            info.Variation.ObjectToFollow = null;

            var shouldUseClipAgePriority = Instance.prioritizeOnDistance &&
                                           (Instance.useClipAgePriority || info.Variation.ParentGroup.useClipAgePriority);

            if (useVector3) {
                info.Source.transform.position = sourcePosition;
                if (Instance.prioritizeOnDistance) {
                    AudioPrioritizer.Set3DPriority(info.Source, shouldUseClipAgePriority);
                }
            } else if (sourceTrans != null) {
                if (attachToSource) {
                    info.Variation.ObjectToFollow = sourceTrans;
                } else {
                    info.Source.transform.position = sourceTrans.position;
                    info.Variation.ObjectToTriggerFrom = sourceTrans;
                }

                if (Instance.prioritizeOnDistance) {
                    AudioPrioritizer.Set3DPriority(info.Source, shouldUseClipAgePriority);
                }
            } else {
                // "2d manner" - from Master Audio location
                if (Instance.prioritizeOnDistance) {
                    AudioPrioritizer.Set2DSoundPriority(info.Source);
                }
                info.Source.transform.localPosition = Vector3.zero;
                // put it back in MA prefab position after being detached.
            }

            var groupVolume = maGroup.groupMasterVolume;
            var busVolume = GetBusVolume(maGroup);

            var varVol = info.OriginalVolume;

            var randomVol = 0f;
            if (info.Variation.useRandomVolume) {
                // random volume
                randomVol = UnityEngine.Random.Range(info.Variation.randomVolumeMin, info.Variation.randomVolumeMax);

                switch (info.Variation.randomVolumeMode) {
                    case SoundGroupVariation.RandomVolumeMode.AddToClipVolume:
                        varVol += randomVol;
                        break;
                    case SoundGroupVariation.RandomVolumeMode.IgnoreClipVolume:
                        varVol = randomVol;
                        break;
                }
            }

            var calcVolume = varVol * groupVolume * busVolume * Instance._masterAudioVolume;

            // set volume to percentage.
            var volume = calcVolume * volumePercentage;
            var targetVolume = volume;

            info.Source.volume = targetVolume;

            // save these for on the fly adjustments afterward
            info.LastPercentageVolume = volumePercentage;
            info.LastRandomVolume = randomVol;

            // ReSharper disable once JoinDeclarationAndInitializer
            bool isActive;

#if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
        isActive = info.Variation.GameObj.active;
#else
            isActive = info.Variation.GameObj.activeInHierarchy;
#endif

            if (!isActive) {
                return null;
            }

            PlaySoundResult result = null;

            if (makePlaySoundResult) {
                result = new PlaySoundResult { ActingVariation = info.Variation };

                if (delaySoundTime > 0f) {
                    result.SoundScheduled = true;
                } else {
                    result.SoundPlayed = true;
                }
            } else {
                forgetSoundPlayed = true;
            }

            var soundType = maGroup.GameObjectName;
            var isChainLoop = maGroup.curVariationMode == MasterAudioGroup.VariationMode.LoopedChain;

            if (isChainLoop) {
                if (!isChaining) {
                    maGroup.ChainLoopCount = 0;
                }

                var objFollow = info.Variation.ObjectToFollow;

                // make sure there isn't 2 chains going, ever!
                if (maGroup.ActiveVoices > 0 && !isChaining) {
                    StopAllOfSound(soundType);
                }

                // restore this because it is lost from the Stop above;
                info.Variation.ObjectToFollow = objFollow;
            }

            info.Variation.Play(pitch, targetVolume, soundType, volumePercentage, targetVolume, pitch, sourceTrans,
                attachToSource, delaySoundTime, isChaining, isSingleSubscribedPlay);

            return result;
        }
        private static void RemoveClipAndRefillIfEmpty(AudioGroupInfo grp, bool isNonSpecific, int? randomIndex,
            List<int> choices, string sType, int pickedChoice, bool loggingEnabledForGrp, bool isSingleVarLoop) {

            if (isSingleVarLoop) {
                grp.Group.ChainLoopCount++; // this doesn't call Refill Sound Group where this normally occurs so this part needs to happen separately
                return;
            }

            if (isNonSpecific && randomIndex.HasValue) {
                // only if successfully played!
                choices.RemoveAt(randomIndex.Value);
                _clipsPlayedBySoundTypeOldestFirst[sType].Add(pickedChoice);

                if (choices.Count == 0) {
                    if (loggingEnabledForGrp) {
                        LogMessage("Refilling Variation pool: " + sType);
                    }

                    RefillSoundGroupPool(sType);
                }
            }

            if (grp.Group.curVariationSequence == MasterAudioGroup.VariationSequence.TopToBottom &&
                grp.Group.useInactivePeriodPoolRefill) {
                UpdateRefillTime(sType, grp.Group.inactivePeriodSeconds);
            }
        }
 private static void SetLastPlayed(AudioGroupInfo grp) {
     grp.LastTimePlayed = Time.realtimeSinceStartup;
     grp.LastFramePlayed = Time.frameCount;
 }
Beispiel #8
0
    void Awake()
    {
        if (GameObject.FindObjectsOfType(typeof(MasterAudio)).Length > 1) {
            Destroy(gameObject);
            Debug.Log("More than one Master Audio prefab exists in this Scene. Destroying the newer one called '" + this.name + "'. You may wish to set up a Bootstrapper Scene so this does not occur.");
            return;
        }

        this.useGUILayout = false;
        soundsLoaded = false;

        innerLoopDelay = new WaitForSeconds(INNER_LOOP_CHECK_INTERVAL);

        var aud = this.GetComponent<AudioSource>();
        if (aud != null) {
            // delete the previewer
            GameObject.Destroy(aud);
        }

        audioSourcesBySoundType.Clear();
        playlistControllersByName.Clear();
        lastTimeSoundGroupPlayed.Clear();

        var plNames = new List<string>();
        AudioResourceOptimizer.ClearAudioClips();

        PlaylistController.Instances = null; // clear the cache
        var playlists = PlaylistController.Instances;
        for (var i = 0; i < playlists.Count; i++) {
            var aList = playlists[i];

            if (plNames.Contains(aList.name)) {
                Debug.LogError("You have more than 1 Playlist Controller with the name '" + aList.name + "'. You must name them all uniquely or the same-named ones will be deleted once they awake.");
                continue;
            } else {
                plNames.Add(aList.name);
            }

            playlistControllersByName.Add(aList.name, aList);
            if (persistBetweenScenes) {
                DontDestroyOnLoad(aList);
            }
        }

        // start up Objects!
        if (persistBetweenScenes) {
            DontDestroyOnLoad(this.gameObject);
        }

        Transform parentGroup;
        List<AudioInfo> sources;

        var playedStatuses = new List<int>();
        AudioSource source;
        AudioGroupInfo _group;
        MasterAudioGroup groupScript;
        randomizer = new Dictionary<string, List<int>>();
        randomizerLeftovers = new Dictionary<string, List<int>>();
        clipsPlayedBySoundTypeOldestFirst = new Dictionary<string, List<int>>();
        string soundType = string.Empty;

        var firstGroupName = string.Empty;

        var allVars = new List<SoundGroupVariation>();

        groupsToRemove = new List<string>(Trans.childCount);

        for (var k = 0; k < Trans.childCount; k++) {
            parentGroup = Trans.GetChild(k);

            sources = new List<AudioInfo>();

            groupScript = parentGroup.GetComponent<MasterAudioGroup>();

            if (groupScript == null) {
                Debug.LogError("MasterAudio could not find 'MasterAudioGroup' script for group '" + parentGroup.name + "'. Skipping this group.");
                continue;
            }

            soundType = parentGroup.name;

            if (string.IsNullOrEmpty(firstGroupName)) {
                firstGroupName = soundType;
            }

            var newWeightedChildren = new List<Transform>();

            SoundGroupVariation variation = null;
            SoundGroupVariation childVariation = null;
            Transform child = null;

            for (int i = 0; i < parentGroup.childCount; i++) {
                child = parentGroup.GetChild(i);
                variation = child.GetComponent<SoundGroupVariation>();
                source = child.GetComponent<AudioSource>();

                var weight = variation.weight;

                for (var j = 0; j < weight; j++) {
                    if (j > 0) {
                        var extraChild = (GameObject)GameObject.Instantiate(child.gameObject, parentGroup.transform.position, Quaternion.identity);
                        extraChild.transform.name = child.gameObject.name;
                        childVariation = extraChild.GetComponent<SoundGroupVariation>();
                        childVariation.weight = 1;

                        newWeightedChildren.Add(extraChild.transform);
                        source = extraChild.GetComponent<AudioSource>();

                        sources.Add(new AudioInfo(childVariation, source, source.volume));
                        allVars.Add(childVariation);

                        if (childVariation.audLocation == MasterAudio.AudioLocation.ResourceFile) {
                            AudioResourceOptimizer.AddTargetForClip(childVariation.resourceFileName, source);
                        }
                    } else {
                        sources.Add(new AudioInfo(variation, source, source.volume));
                        allVars.Add(variation);

                        if (variation.audLocation == MasterAudio.AudioLocation.ResourceFile) {
                            var resFileName = AudioResourceOptimizer.GetLocalizedFileName(variation.useLocalization, variation.resourceFileName);
                            AudioResourceOptimizer.AddTargetForClip(resFileName, source);
                        }
                    }
                }
            }

            // attach extra children from weight property.
            for (var i = 0; i < newWeightedChildren.Count; i++) {
                newWeightedChildren[i].parent = parentGroup;
            }

            _group = new AudioGroupInfo(sources, groupScript);
            if (groupScript.isSoloed) {
                soloedGroups.Add(groupScript);
            }

            if (audioSourcesBySoundType.ContainsKey(soundType)) {
                Debug.LogError("You have more than one SoundGroup named '" + soundType + "'. Ignoring the 2nd one. Please rename it.");
                continue;
            }

            _group._sources.Sort(delegate(AudioInfo x, AudioInfo y) {
                return x.variation.name.CompareTo(y.variation.name);
            });

            // added code for persistent group volume
            var persistentVolume = PersistentAudioSettings.GetGroupVolume(soundType);
            if (persistentVolume.HasValue) {
                _group._group.groupMasterVolume = persistentVolume.Value;
            }

            audioSourcesBySoundType.Add(soundType, _group);

            for (var i = 0; i < sources.Count; i++) {
                playedStatuses.Add(i);
            }

            randomizer.Add(soundType, playedStatuses);
            randomizerLeftovers.Add(soundType, new List<int>(playedStatuses.Count));
            clipsPlayedBySoundTypeOldestFirst.Add(soundType, new List<int>());

            playedStatuses = new List<int>();
        }

        busFades.Clear();
        groupFades.Clear();

        Playlist pl = null;
        float firstSongLength = 0f;

        // check Syncrhonized Playlists for problems!
        for (var i = 0; i < musicPlaylists.Count; i++) {
            pl = musicPlaylists[i];
            if (pl.songTransitionType != SongFadeInPosition.SynchronizeClips) {
                continue;
            }

            if (pl.MusicSettings.Count < 2) {
                continue;
            }

            var songOne = pl.MusicSettings[0].clip;
            if (songOne == null) {
                continue;
            }

            firstSongLength = songOne.length;
            for (var s = 1; s < pl.MusicSettings.Count; s++) {
                var clip = pl.MusicSettings[s].clip;
                if (clip == null) {
                    continue;
                }

                if (clip.length != firstSongLength) {
                    Debug.LogError("Playlist '" + pl.playlistName + "' is marked as Synchronized but the clip lengths are not all the same within the Playlist. Clips may not synchronize as intended.");
                    break;
                }
            }
        }

        // initialize persistent bus volumes
        for (var i = 0; i < groupBuses.Count; i++) {
            var busName = groupBuses[i].busName;
            var busVol = PersistentAudioSettings.GetBusVolume(busName);

            if (!busVol.HasValue) {
                continue;
            }

            SetBusVolumeByName(busName, busVol.Value);
        }

        // populate ducking sounds dictionary
        duckingBySoundType.Clear();
        for (var i = 0; i < musicDuckingSounds.Count; i++) {
            var aDuck = musicDuckingSounds[i];
            duckingBySoundType.Add(aDuck.soundType, aDuck);
        }

        soundsLoaded = true;

        warming = true;

        // pre-warm the code so the first sound played for real doesn't have to JIT and be slow.
        if (!string.IsNullOrEmpty(firstGroupName)) {
            var result = PlaySound3DFollowTransform(firstGroupName, Trans, 0f, 1f, 0f, null);
            if (result != null && result.SoundPlayed) {
                result.ActingVariation.Stop();
            }
        }

        FireCustomEvent("FakeEvent", this.trans.position);

        // Event Sounds warmer
        var evts = GameObject.FindObjectsOfType(typeof(EventSounds));
        if (evts.Length > 0) {
            var evt = evts[0] as EventSounds;
            evt.PlaySounds(evt.particleCollisionSound, EventSounds.EventType.UserDefinedEvent);
        }

        // done warming
        warming = false;

        for (var i = 0; i < allVars.Count; i++) {
            allVars[i].DisableUpdater();
        }

        // fixed: make sure this happens before Playlists start or the volume won't be right.
        PersistentAudioSettings.RestoreMasterSettings();
    }
    private static PlaySoundResult PlaySoundIfAvailable(string soundGroupName,
            AudioInfo info,
            Vector3 sourcePosition,
            float volumePercentage,
            ref bool forgetSoundPlayed,
            float? pitch = null,
            AudioGroupInfo audioGroup = null,
            Transform sourceTrans = null,
            bool attachToSource = false,
            float delaySoundTime = 0f,
            bool useVector3 = false,
            bool makePlaySoundResult = false,
			bool isChaining = false)
    {

        if (info.source == null)
        {
            // this avoids false errors when stopping the game (from became invisible event callers)
            return null;
        }

        MasterAudioGroup maGroup = audioGroup._group;

        if (info.source.audio.isPlaying)
        {
            var playedPercentage = AudioUtil.GetAudioPlayedPercentage(info.source);
            var retriggerPercent = maGroup.retriggerPercentage;

            if (playedPercentage < retriggerPercent)
            {
                return null; // wait for this to stop playing or play further.
            }
        }

        info.variation.Stop();
        info.variation.ObjectToFollow = null;

        if (useVector3)
        {
            info.source.transform.position = sourcePosition;
            if (MasterAudio.Instance.prioritizeOnDistance)
            {
                AudioPrioritizer.Set3dPriority(info.source);
            }
        }
        else if (sourceTrans != null)
        {
            if (attachToSource)
            {
                info.variation.ObjectToFollow = sourceTrans;
            }
            else
            {
                info.source.transform.position = sourceTrans.position;
            }

            if (MasterAudio.Instance.prioritizeOnDistance)
            {
                AudioPrioritizer.Set3dPriority(info.source);
            }
        }
        else
        {
            // "2d manner"
            if (MasterAudio.Instance.prioritizeOnDistance)
            {
                AudioPrioritizer.Set2dSoundPriority(info.source);
            }
            info.source.transform.localPosition = Vector3.zero; // put it back in MA prefab position after being detached.
        }

        var groupVolume = maGroup.groupMasterVolume;
        var busVolume = GetBusVolume(maGroup);

        float calcVolume = info.originalVolume * groupVolume * busVolume * MasterAudio.Instance.masterAudioVolume;

        // set volume to percentage.
        float volume = calcVolume * volumePercentage;

        // random volume
        var randomVol = 0f;
        if (info.variation.randomVolume != 0f)
        {
            randomVol = UnityEngine.Random.Range(-info.variation.randomVolume, info.variation.randomVolume);
        }

        var targetVolume = volume + randomVol;

        info.source.audio.volume = targetVolume;

        // save these for on the fly adjustments afterward
        info.lastPercentageVolume = volumePercentage;
        info.lastRandomVolume = randomVol;

        bool isActive = false;

#if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
        isActive = info.source.audio.gameObject.active;
#else
			isActive = info.source.audio.gameObject.activeInHierarchy;
#endif

        if (!isActive)
        {
            return null;
        }

        PlaySoundResult result = null;

        if (makePlaySoundResult)
        {
            result = new PlaySoundResult();
            result.ActingVariation = info.variation;

            if (delaySoundTime > 0f)
            {
                result.SoundScheduled = true;
            }
            else
            {
                result.SoundPlayed = true;
            }
        }
        else
        {
            forgetSoundPlayed = true;
        }

        var playSoundParams = new SoundGroupVariation.PlaySoundParams(maGroup.name,
              volumePercentage,
              calcVolume,
              pitch,
              sourceTrans,
              attachToSource,
              delaySoundTime,
              maGroup.curVariationMode == MasterAudioGroup.VariationMode.LoopedChain);

		
		if (playSoundParams.isChainLoop && !isChaining) {
			maGroup.ChainLoopCount = 0;
		}
		
        if (playSoundParams.isChainLoop)
        {
            // make sure there isn't 2 going, ever
            MasterAudio.StopAllOfSound(playSoundParams.soundType);
        }

        info.variation.Play(pitch, targetVolume, playSoundParams);

        if (delaySoundTime == 0f)
        {
            // sound play worked! Duck music if a ducking sound.
            var ma = MasterAudio.Instance;

            var matchingDuck = ma.musicDuckingSounds.Find(delegate(DuckGroupInfo obj)
            {
                return obj.soundType == soundGroupName;
            });

            if (ma.EnableMusicDucking && matchingDuck != null)
            {
                // duck music
                var duckLength = info.source.audio.clip.length;
                var duckPitch = info.source.pitch;

                var pcs = PlaylistController.Instances;
                for (var i = 0; i < pcs.Count; i++)
                {
                    pcs[i].DuckMusicForTime(duckLength, duckPitch, matchingDuck.riseVolStart);
                }

                if (pcs.Count == 0)
                {
                    Debug.LogWarning("Playlist Controller is not in the Scene. Cannot duck music.");
                }
            }
        }


        return result;
    }