using System; using UnityEngine; using CriWare; using CriWare.Assets; using PhxhSDK; //基于Criware的音频控制类 public class AudioCriware: AudioBase { private CriAtomSourceForAsset _criAtomSource; private CriAtomAssets _criAtomAssets; private CriAtomAcbAsset _initAcb; private CriAtomCueReference _cue; private GameObject _rootGo; private int _cueId = -1; private static int _cueIDs = 0; public static int CueIDGen() { return ++_cueIDs; } public GameObject RootGo => _rootGo; public CriAtomSourceForAsset audioSource { get => _criAtomSource; } protected AudioCriware(CriAtomAcbAsset acbAsset, bool loop, Transform sourceTransform, bool is3D, string cueName, Audio.AudioInfo audioInfo) { if (sourceTransform == null) { this.sourceTransform = AudioManager.Instance.initGameObject.transform; _rootGo = null; } else { this.sourceTransform = sourceTransform; _rootGo = sourceTransform.gameObject; is3D = true; } this.persist = audioInfo.persist; targetVolume = audioInfo.volume; initTargetVolume = audioInfo.volume; this.volume = audioInfo.volume; tempFadeSeconds = -1; this.fadeInSeconds = audioInfo.fadeInValue; this.fadeOutSeconds = audioInfo.fadeOutValue; //playState = PlayState.Stopped; playState = PlayState.Loading; //等acb文件加载完成后挂source acbAsset.OnLoaded += OnAcbLoaded(acbAsset, cueName, loop, is3D); } private Action OnAcbLoaded(CriAtomAcbAsset acbAsset, string cueName, bool isLoop = false, bool is3D = false) { CreateAudiosource(acbAsset, isLoop, is3D); if(AudioManager.Instance.IsAnalyzer) { _criAtomSource.AttachToAnalyzer(AudioManager.Instance.analyzer); } if (cueName.Length > 0) { PlayByCueName(cueName); } else { Play(); } return null; } private bool _GetFreeAudioSource() { return false; } public void CreateAudiosource(CriAtomAcbAsset acbAsset, bool loop = false, bool is3D = false) { _criAtomSource = sourceTransform.gameObject.AddComponent(); CriAtomCueReference cueReference = new CriAtomCueReference(acbAsset, CueIDGen());//CueIDGen()); _criAtomSource.Cue = cueReference; _criAtomSource.loop = loop; _criAtomSource.volume = 1f; _criAtomSource.use3dPositioning = is3D; //_criAtomSource.playOnStart = true; _initAcb = acbAsset; } public override void Play(float volume) { if (_criAtomSource == null) { CreateAudiosource(_initAcb, loop); } _criAtomSource.Play(); playState = PlayState.Playing; fadeInterpolater = 0f; onFadeStartVolume = this.volume; targetVolume = volume; } public void PlayByCueName(string cueName, bool isLoop = false) { if (_criAtomSource == null) { CreateAudiosource(_initAcb, loop); } _criAtomSource.Play(cueName); playState = PlayState.Playing; fadeInterpolater = 0f; onFadeStartVolume = this.volume; targetVolume = volume; this.loop = isLoop; } public override void Play(string cueName, bool isLoop = false) { PlayByCueName(cueName, isLoop); } public override void Pause() { _criAtomSource.Pause(true); playState = PlayState.Paused; } //继续播放 public override void Resume() { _criAtomSource.Pause(false); playState = PlayState.Playing; } public void SetPitch(float _pitch) { if (_criAtomSource != null) { _criAtomSource.pitch = _pitch; } } public void SetIs3D(bool is3D) { _criAtomSource.use3dPositioning = is3D; } public override void Update() { if (!_criAtomSource) { return; } activated = true; if (Math.Abs(volume - targetVolume) > 0.01f) { float fadeValue; fadeInterpolater += Time.unscaledDeltaTime; if (volume > targetVolume) { fadeValue = Math.Abs(tempFadeSeconds + 1) > 0.01f ? tempFadeSeconds : fadeOutSeconds; } else { fadeValue = Math.Abs(tempFadeSeconds + 1) > 0.01f ? tempFadeSeconds : fadeInSeconds; } volume = Mathf.Lerp(onFadeStartVolume, targetVolume, fadeInterpolater / fadeValue); } else if (Math.Abs(tempFadeSeconds - (-1)) > 0.01) { tempFadeSeconds = -1; } switch (audioType) { case AudioType.Music: { _criAtomSource.volume = volume * AudioManager.Instance.GlobalMusicVolume * AudioManager.Instance.GlobalVolume; break; } case AudioType.Sound: { _criAtomSource.volume = volume * AudioManager.Instance.GlobalSoundsVolume * AudioManager.Instance.GlobalVolume; break; } } if (volume == 0f && IsStopped) { _criAtomSource.Stop(); } // Update playing status if (_criAtomSource.status != CriAtomSourceBase.Status.Playing && !Application.isFocused) { //playState = PlayState.Playing; playState = PlayState.Stopped; } } }