using System; using System.Collections.Generic; using UnityEngine; using CriWare; using CriWare.Assets; using PhxhSDK; //基于Criware的音频控制类 public class AudioCriware: AudioBase { private CriAtomSourceForAsset _criAtomSource; private CriAtomExPlayback criAtomExPlayback; private CriAtomAssets _criAtomAssets; private CriAtomAcbAsset _initAcb; private CriAtomCueReference _cue; private int _playID = -1; private bool _isSpeak; private GameObject _posGo; public static Dictionary CueReferenceDic = new(); public GameObject PosGo { get => _posGo; set =>_posGo = value; } public CriAtomExPlayback CriAtomPlayback => criAtomExPlayback; public CriAtomAcbAsset AcbAsset => _initAcb; public int PlayID => _playID; //private GameObject _rootGo; private int _cueId = -1; private static int _cueIDs = 0; public static int CueIDGen() { return ++_cueIDs; } public int GenPlayID() { return ++_playID; } //public GameObject RootGo => _rootGo; public CriAtomSourceForAsset audioSource { get => _criAtomSource; } protected AudioCriware(CriAtomAcbAsset acbAsset, bool loop, GameObject posObj, GameObject rootGo, bool is3D, string cueName, AudioInfo audioInfo): base() { if (!posObj) { //DebugUtil.LogError("音频对象池内,可取对象为空!!!"); } _posGo = posObj; _rootGo = rootGo; sourceTransform = _rootGo.transform; persist = audioInfo.persist; targetVolume = audioInfo.volume; initTargetVolume = audioInfo.volume; volume = audioInfo.volume; tempFadeSeconds = -1; fadeInSeconds = audioInfo.fadeInValue; fadeOutSeconds = audioInfo.fadeOutValue; //playState = PlayState.Stopped; playState = PlayState.Loading; //等acb文件加载完成后挂source //acbAsset.OnLoaded += OnAcbLoaded(acbAsset, cueName, loop, is3D); //OnAcbLoaded(acbAsset, cueName, loop, is3D); } protected virtual void AttachAnalyzer() { } //加载音频文件完成后的操作 protected Action OnAcbLoaded(CriAtomAcbAsset acbAsset, string cueName, bool isLoop = false, bool is3D = false) { CreateAudiosource(acbAsset, isLoop, is3D); AttachAnalyzer(); if (cueName.Length > 0) { PlayByCueName(cueName); } else { Play(); } return null; } public void Play() { base.Play(); GenPlayID(); playState = PlayState.Playing; } private bool _GetFreeAudioSource() { return false; } public void CreateAudiosource(CriAtomAcbAsset acbAsset, bool loop = false, bool is3D = false) { _criAtomSource = _rootGo.GetComponent(); if (!_criAtomSource) { _criAtomSource = _rootGo.AddComponent(); } //CriAtomCueReference cueReference = new CriAtomCueReference(acbAsset, CueIDGen());//CueIDGen()); var cueReference = CueReferenceDic[acbAsset]; _criAtomSource.Cue = cueReference; _criAtomSource.loop = loop; _criAtomSource.volume = 1f; _initAcb = acbAsset; } public void Stop() { base.Stop(); _criAtomSource.Stop(); } public override void Play(float volume) { if (_criAtomSource == null) { CreateAudiosource(_initAcb, loop); } criAtomExPlayback = _criAtomSource.Play(); playState = PlayState.Playing; fadeInterpolater = 0f; onFadeStartVolume = this.volume; targetVolume = volume; GenPlayID(); } public void PlayByCueName(string cueName, bool isLoop = false) { if (_criAtomSource == null) { CreateAudiosource(_initAcb, loop); } criAtomExPlayback = _criAtomSource.Play(cueName); playState = PlayState.Playing; fadeInterpolater = 0f; onFadeStartVolume = this.volume; targetVolume = volume; this.loop = isLoop; GenPlayID(); } public override void Play(string cueName, bool isLoop = false) { PlayByCueName(cueName, isLoop); GenPlayID(); } 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 void SetAcbAsset(CriAtomAcbAsset acbAsset) { _initAcb = acbAsset; if (_criAtomSource) { _criAtomSource.Cue = CueReferenceDic[acbAsset]; } } public void SetIsSpeak(bool isSpeak) { _isSpeak = isSpeak; } 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: { if (_isSpeak) { _criAtomSource.volume = volume * AudioManager.Instance.GlobalSpeakVolume * AudioManager.Instance.GlobalVolume; break; } _criAtomSource.volume = volume * AudioManager.Instance.GlobalSoundsVolume * AudioManager.Instance.GlobalVolume; break; } } if (volume == 0f && IsStopped) { if (audioType == AudioType.Music) { DebugUtil.LogError($"Music Stop ID:{audioID}"); } _criAtomSource.Stop(); } if (IsStopped && _criAtomSource.status != CriAtomSourceBase.Status.Stop) { _criAtomSource.Stop(); } // Update playing status // if (_criAtomSource.status != CriAtomSourceBase.Status.Playing && !Application.isFocused) // { //playState = PlayState.Playing; // if (audioType == AudioType.Music) // { // DebugUtil.LogError($"Music Stop ID:{audioID}"); // } //playState = PlayState.Stopped; //} if (_criAtomSource.status == CriAtomSourceBase.Status.Stop && playState != PlayState.Stopped) { // if (audioType == AudioType.Music) // { // DebugUtil.LogError($"Music Stop ID:{audioID}"); // } playState = PlayState.Stopped; } if (_criAtomSource.status == CriAtomSourceBase.Status.PlayEnd && playState != PlayState.Stopped) { playState = PlayState.Stopped; } } }