You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

220 lines
7.2 KiB

using UnityEngine;
namespace ET
{
public class SoundComponentAwakeSystem: AwakeSystem<SoundComponent>
{
public override void Awake(SoundComponent self)
{
self.Awake();
}
}
[FriendClass(typeof(SoundComponent))]
public static class SoundComponentSystem
{
public static void Awake(this SoundComponent self)
{
SoundComponent.Instance = self;
self._musicMute = PlayerPrefs.GetInt("MusicMute", 0) == 1;
self._soundMute = PlayerPrefs.GetInt("SoundMute", 0) == 1;
self.root = new GameObject("SoundDatas").transform;
GameObject.DontDestroyOnLoad(self.root.gameObject);
}
private static bool IsContainClip(this SoundComponent self, string clipName)
{
lock (self.m_clips)
{
if (self.m_clips.ContainsKey(clipName))
return true;
return false;
}
}
private static SoundData GetAudioSource(this SoundComponent self, string clipName)
{
if (self.IsContainClip(clipName))
return self.m_clips[clipName];
return null;
}
private static void AddClip(this SoundComponent self, string clipName, SoundData data, SoundType type)
{
lock (self.m_clips)
{
data.IsPause = false;
data.transform.transform.SetParent(self.root);
data.Sound = type;
if (self.IsContainClip(clipName))
{
self.m_clips[clipName] = data;
self._allClips[type][clipName] = data;
}
else
{
self.m_clips.Add(clipName, data);
self._allClips[type].Add(clipName, data);
}
}
}
/// <summary>
/// 短暂的声音和特效
/// 无法暂停
/// 异步加载音效
/// </summary>
public static async void PlayClip(this SoundComponent self, string clipName, float volume = 1)
{
SoundData sd = await self.LoadSound(clipName);
if (sd != null)
{
sd.volume = Mathf.Clamp(volume, 0, 1);
sd.Mute = self.SoundMute;
if (!self.IsContainClip(clipName))
{
self.AddClip(clipName, sd, SoundType.Sound);
}
self.PlayMusic(clipName, sd);
}
else
{
Log.Error($"没有此音效 ={ clipName}");
}
}
/// <summary>
/// 播放长音乐 背景音乐等
/// 可以暂停 继续播放
/// 异步加载音效
/// </summary>
/// <param name="clipName">声音的预设名字(不包括前缀路径名)</param>
/// <param name="delay">延迟播放 单位秒</param>
/// <param name="volume">音量</param>
/// <param name="isloop">是否循环播放</param>
/// /// <param name="forceReplay">是否强制重头播放</param>
public static async void PlayMusic(this SoundComponent self, string clipName, ulong delay = 0, float volume = 1, bool isloop = false, bool forceReplay = false)
{
SoundData sd = await self.LoadSound(clipName);
if (sd != null)
{
sd.isForceReplay = forceReplay;
sd.isLoop = isloop;
sd.delay = delay;
sd.volume = Mathf.Clamp(volume, 0, 1);
sd.Mute = self.MusicMute;
if (!self.IsContainClip(clipName))
{
self.AddClip(clipName, sd, SoundType.Music);
}
self.PlayMusic(clipName, sd);
}
else
{
Log.Error($"没有此音效 ={ clipName}");
}
}
//加载声音
private static async ETTask<SoundData> LoadSound(this SoundComponent self, string soundName)
{
if (!SoundComponent.abSounds.ContainsKey(soundName) || SoundComponent.abSounds[soundName] == null)
{
var prefab = await YooAssetComponent.Instance.LoadAssetAsync<GameObject>("Sound_"+soundName);
SoundComponent.abSounds.Add(soundName, GameObject.Instantiate(prefab).GetComponent<SoundData>());
YooAssetComponent.Instance.Release(prefab);
}
return SoundComponent.abSounds[soundName];
}
//播放SoundData
private static void PlayMusic(this SoundComponent self, string clipName, SoundData asource)
{
if (null == asource)
return;
bool forceReplay = asource.isForceReplay;
asource.audio.volume = asource.volume * self.SoundVolume;
asource.audio.loop = asource.isLoop;
if (!forceReplay)
{
if (!asource.IsPlaying)
{
if (!asource.IsPause)
asource.audio.Play(asource.delay);
else
self.Resume(clipName);
}
}
else
{
asource.audio.PlayDelayed(asource.delay);
asource.audio.PlayScheduled(0);
}
}
/// <summary>
/// 停止并销毁声音
/// </summary>
/// <param name="clipName"></param>
public static void Stop(this SoundComponent self, string clipName)
{
SoundData data = self.GetAudioSource(clipName);
if (null != data)
{
if (self._allClips[data.Sound].ContainsKey(clipName))
{
self._allClips[data.Sound].Remove(clipName);
}
self.m_clips.Remove(clipName);
SoundComponent.abSounds.Remove(clipName);
data.Dispose();
}
}
/// <summary>
/// 暂停声音
/// </summary>
/// <param name="clipName"></param>
public static void Pause(this SoundComponent self, string clipName)
{
SoundData data = self.GetAudioSource(clipName);
if (null != data)
{
data.IsPause = true;
data.audio.Pause();
}
}
/// <summary>
/// 继续播放
/// </summary>
/// <param name="clipName"></param>
public static void Resume(this SoundComponent self, string clipName)
{
SoundData data = self.GetAudioSource(clipName);
if (null != data)
{
data.IsPause = false;
data.audio.UnPause();
}
}
/// <summary>
/// 销毁所有声音
/// </summary>
public static void DisposeAll(this SoundComponent self)
{
foreach (var allClip in self._allClips.Values)
{
allClip.Clear();
}
foreach (var item in self.m_clips)
{
item.Value.Dispose();
}
self.m_clips.Clear();
}
}
}