Files
BingoGrassland/Assets/BingoSun/Scripts/UnityManager/Audio.cs
T

671 lines
18 KiB
C#
Raw Normal View History

2026-04-20 13:49:36 +08:00
using System;
using FairyGUI;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BingoBrain.Asset;
using UnityEngine.Events;
namespace BingoBrain.Core
{
public sealed class Audio : BaseUnity<Audio>
{
#region
public const bool IsUnscaleTime = true;
private Dictionary<string, AudioClip> audioClipCacheDict = new Dictionary<string, AudioClip>();
private GameObject newEffectSourcesRoot;
private GameObject dynamicEffectSourcesRoot;
[HideInInspector] public AudioListener audioListener;
[HideInInspector] public AudioSource bgmSource;
[HideInInspector] public AudioSource effectSource;
[HideInInspector] public List<AudioSource> newEffectSources = new List<AudioSource>();
[HideInInspector] public List<AudioSource> dynamicEffectSources = new List<AudioSource>();
[HideInInspector] public List<AudioSource> unscaleTimeSounds = new List<AudioSource>();
[HideInInspector] public float currUISoundVolume = 1;
#endregion
#region
private bool isOpenBGM;
public bool IsOpenBGM
{
get { return isOpenBGM; }
set
{
isOpenBGM = value;
RrysKit.WriteBool(FsyConst.AudioMgr_isOpenBGM, isOpenBGM);
if (!bgmSource) return;
bgmSource.enabled = isOpenBGM;
if (isOpenBGM)
{
bgmSource.Play();
}
else
{
bgmSource.Pause();
}
}
}
private bool isOpenEffect;
public bool IsOpenEffect
{
get { return isOpenEffect; }
set
{
isOpenEffect = value;
RrysKit.WriteBool(FsyConst.AudioMgr_isOpenEffect, isOpenEffect);
GRoot.inst.soundVolume = isOpenEffect ? currUISoundVolume : 0f;
if (isOpenEffect)
{
GRoot.inst.EnableSound();
}
else
{
GRoot.inst.DisableSound();
}
}
}
private void InitAudioMode()
{
isOpenBGM = RrysKit.ReadBool(FsyConst.AudioMgr_isOpenBGM, true);
isOpenEffect = RrysKit.ReadBool(FsyConst.AudioMgr_isOpenEffect, true);
GRoot.inst.soundVolume = 1;
currUISoundVolume = GRoot.inst.soundVolume;
GRoot.inst.soundVolume = isOpenEffect ? currUISoundVolume : 0f;
}
public void PauseAllSource()
{
bgmSource.Pause();
IsOpenEffect = false;
effectSource.Pause();
for (int i = 0; i < newEffectSources.Count; i++)
{
newEffectSources[i].Pause();
}
for (int i = 0; i < dynamicEffectSources.Count; i++)
{
dynamicEffectSources[i].Pause();
}
GRoot.inst.DisableSound();
}
public void UnPauseAllSource()
{
bgmSource.UnPause();
IsOpenEffect = true;
effectSource.UnPause();
for (int i = 0; i < newEffectSources.Count; i++)
{
newEffectSources[i].UnPause();
}
for (int i = 0; i < dynamicEffectSources.Count; i++)
{
dynamicEffectSources[i].UnPause();
}
GRoot.inst.EnableSound();
}
#endregion
#region
public float BgmVolume
{
get { return bgmSource.volume; }
set { bgmSource.volume = value; }
}
public float EffectVolume
{
get { return effectSource.volume; }
set { effectSource.volume = value; }
}
public float newEffectVolume
{
get
{
for (int i = 0; i < newEffectSources.Count; i++)
{
return newEffectSources[i].volume;
}
return 0;
}
set
{
for (int i = 0; i < newEffectSources.Count; i++)
{
newEffectSources[i].volume = value;
}
}
}
public float dynamicEffectVolume
{
get
{
for (int i = 0; i < dynamicEffectSources.Count; i++)
{
return dynamicEffectSources[i].volume;
}
return 0;
}
set
{
for (int i = 0; i < dynamicEffectSources.Count; i++)
{
dynamicEffectSources[i].volume = value;
}
}
}
#endregion
#region
public override void Init()
{
base.Init();
AppDispatcher.Instance.AddListener(CsjInfoC.TimeScale_Change, OnTimeScaleChange);
audioListener = gameObject.AddComponent<AudioListener>();
bgmSource = gameObject.AddComponent<AudioSource>();
bgmSource.playOnAwake = false;
bgmSource.loop = true;
effectSource = gameObject.AddComponent<AudioSource>();
effectSource.playOnAwake = false;
effectSource.loop = false;
newEffectSourcesRoot = new GameObject("NewEffectSources");
newEffectSourcesRoot.transform.SetParent(gameObject.transform, false);
dynamicEffectSourcesRoot = new GameObject("DynamicEffectSources");
dynamicEffectSourcesRoot.transform.SetParent(gameObject.transform, false);
InitAudioMode();
}
public override void Dispose()
{
base.Dispose();
AppDispatcher.Instance.RemoveListener(CsjInfoC.TimeScale_Change, OnTimeScaleChange);
}
public void InitDefaultButtonClickSound(string btnSound)
{
string defaultSound = DoConst.UIButtonDefault;
if (!string.IsNullOrEmpty(btnSound))
{
defaultSound = btnSound;
}
BetKit.Instance.LoadAudio("Audio", defaultSound, audioClip =>
{
if (audioClip != null)
{
UIConfig.buttonSound = new NAudioClip(audioClip);
UIConfig.buttonSoundVolumeScale = 1;
}
});
}
private void OnTimeScaleChange(object value)
{
if (unscaleTimeSounds.Count != 0)
{
for (int i = 0; i < unscaleTimeSounds.Count; i++)
{
AudioSource audioSource = unscaleTimeSounds[i];
if (audioSource)
{
audioSource.pitch = Jsvva.NormalTimeScale;
}
}
}
}
#endregion
#region :
public void PlayBGM(string audioName, bool isUnscaleTime = IsUnscaleTime)
{
if (string.IsNullOrEmpty(audioName)) return;
string curName;
if (bgmSource.clip == null)
{
curName = null;
}
else
{
curName = bgmSource.clip.name;
}
if (curName != audioName)
{
AudioClip currClip = null;
if (audioClipCacheDict.ContainsKey(audioName))
{
currClip = audioClipCacheDict[audioName];
}
else
{
currClip = BetKit.Instance.LoadAsset<AudioClip>("Audio", audioName);
}
if (currClip != null)
{
bgmSource.clip = currClip;
if (!isOpenBGM)
{
return;
}
if (isUnscaleTime)
{
if (!unscaleTimeSounds.Contains(bgmSource))
{
unscaleTimeSounds.Add(bgmSource);
}
}
else
{
if (unscaleTimeSounds.Contains(bgmSource))
{
unscaleTimeSounds.Remove(bgmSource);
}
}
bgmSource.pitch = isUnscaleTime ? Jsvva.NormalTimeScale : Jsvva.GetTimeScale();
bgmSource.Play();
}
}
}
public void StopBGM()
{
bgmSource.Stop();
bgmSource.clip = null;
}
#endregion
#region :
public void PlayOnceEffect(string audioName, bool isLoop = false, bool isUnscaleTime = IsUnscaleTime)
{
if (!isOpenEffect || string.IsNullOrEmpty(audioName)) return;
string currName;
AudioClip currClip = null;
if (effectSource.clip == null)
{
currName = null;
}
else
{
currClip = effectSource.clip;
currName = currClip.name;
}
if (currName != audioName)
{
if (audioClipCacheDict.ContainsKey(audioName))
{
currClip = audioClipCacheDict[audioName];
}
else
{
currClip = BetKit.Instance.LoadAsset<AudioClip>("Audio", audioName);
}
}
if (currClip)
{
if (effectSource.loop != isLoop)
{
effectSource.loop = isLoop;
}
effectSource.clip = currClip;
if (isUnscaleTime)
{
if (!unscaleTimeSounds.Contains(effectSource))
{
unscaleTimeSounds.Add(effectSource);
}
}
else
{
if (unscaleTimeSounds.Contains(effectSource))
{
unscaleTimeSounds.Remove(effectSource);
}
}
effectSource.pitch = isUnscaleTime ? Jsvva.NormalTimeScale : Jsvva.GetTimeScale();
effectSource.Play();
}
}
public void PlayFullOnceEffect(string audioName)
{
if (!effectSource.isPlaying)
{
PlayOnceEffect(audioName);
}
}
public void StopOnceEffect()
{
effectSource.Stop();
effectSource.clip = null;
}
public void PauseOnceEffect()
{
effectSource.Pause();
}
public void ContinuousOnceEffect()
{
effectSource.Play();
}
#endregion
#region
public AudioSource NewAudioSource()
{
AudioSource newEffectSource = newEffectSourcesRoot.AddComponent<AudioSource>();
newEffectSource.playOnAwake = false;
newEffectSource.loop = false;
newEffectSources.Add(newEffectSource);
return newEffectSource;
}
public void PlayOnceEffect(AudioSource source, string audioName, bool isLoop = false,
bool isUnscaleTime = IsUnscaleTime)
{
if (!isOpenEffect || string.IsNullOrEmpty(audioName)) return;
string currName;
AudioClip currClip = null;
if (source.clip == null)
{
currName = null;
}
else
{
currClip = source.clip;
currName = currClip.name;
}
if (currName != audioName)
{
if (audioClipCacheDict.ContainsKey(audioName))
{
currClip = audioClipCacheDict[audioName];
}
else
{
currClip = BetKit.Instance.LoadAsset<AudioClip>("Audio", audioName);
}
}
if (currClip)
{
if (source.loop != isLoop)
{
source.loop = isLoop;
}
source.clip = currClip;
if (isUnscaleTime)
{
if (!unscaleTimeSounds.Contains(source))
{
unscaleTimeSounds.Add(source);
}
}
else
{
if (unscaleTimeSounds.Contains(source))
{
unscaleTimeSounds.Remove(source);
}
}
source.pitch = isUnscaleTime ? Jsvva.NormalTimeScale : Jsvva.GetTimeScale();
source.Play();
}
}
public void PlayFullOnceEffect(AudioSource source, string audioName)
{
if (!source.isPlaying)
{
PlayOnceEffect(source, audioName);
}
}
public void StopOnceEffect(AudioSource source)
{
source.Stop();
source.clip = null;
}
#endregion
#region :
public AudioSource PlayDynamicEffect(string audioName, float delay = 0, bool isLoop = false,
bool isUnscaleTime = IsUnscaleTime)
{
if (!isOpenEffect || string.IsNullOrEmpty(audioName)) return null;
AudioSource effectSourceCom = null;
for (int i = 0; i < dynamicEffectSources.Count; i++)
{
AudioSource sourceItem = dynamicEffectSources[i];
if (!sourceItem.isPlaying)
{
effectSourceCom = sourceItem;
break;
}
}
if (effectSourceCom == null)
{
effectSourceCom = dynamicEffectSourcesRoot.AddComponent<AudioSource>();
effectSourceCom.playOnAwake = false;
dynamicEffectSources.Add(effectSourceCom);
}
if (effectSourceCom.loop != isLoop)
{
effectSourceCom.loop = isLoop;
}
string curName;
AudioClip currClip = null;
if (effectSourceCom.clip == null)
{
curName = null;
}
else
{
currClip = effectSourceCom.clip;
curName = currClip.name;
}
var playAction = new UnityAction(delegate
{
if (currClip != null)
{
effectSourceCom.clip = currClip;
if (isUnscaleTime)
{
if (!unscaleTimeSounds.Contains(effectSourceCom))
{
unscaleTimeSounds.Add(effectSourceCom);
}
}
else
{
if (unscaleTimeSounds.Contains(effectSourceCom))
{
unscaleTimeSounds.Remove(effectSourceCom);
}
}
effectSourceCom.pitch =
isUnscaleTime ? Jsvva.NormalTimeScale : Jsvva.GetTimeScale();
if (delay == 0)
{
effectSourceCom.Play();
}
else
{
effectSourceCom.PlayDelayed(delay);
}
}
});
if (curName != audioName)
{
if (audioClipCacheDict.ContainsKey(audioName))
{
currClip = audioClipCacheDict[audioName];
playAction();
}
else
{
var path = new StringBuilder("Audio");
var strs = audioName.Split('.');
var assetName = strs.Last();
if (strs.Length > 1)
{
var assetUrl = audioName.Replace($".{assetName}", string.Empty);
path.Append(".").Append(assetUrl);
}
BetKit.Instance.LoadAudio(path.ToString(), assetName, (clip) =>
{
currClip = clip;
audioClipCacheDict[audioName] = clip;
playAction();
});
}
}
else
{
try
{
if (delay == 0)
{
effectSourceCom.Play();
}
else
{
effectSourceCom.PlayDelayed(delay);
}
}
catch (System.Exception)
{
}
}
return effectSourceCom;
}
#endregion
#region UI声音:
public void PlayUIButtonAudio()
{
PlayOnceEffect(DoConst.UIButtonDefault);
}
#endregion UI声音
#region :
public void PlayGameAudio(string audioName, float delay = 0, bool isLoop = false,
bool isUnscaleTime = IsUnscaleTime)
{
PlayDynamicEffect(audioName, delay, isLoop, isUnscaleTime);
}
#endregion
}
}