using UnityEngine; namespace ET { public class SoundComponentAwakeSystem: AwakeSystem { 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); } } } /// /// 短暂的声音和特效 /// 无法暂停 /// 异步加载音效 /// 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}"); } } /// /// 播放长音乐 背景音乐等 /// 可以暂停 继续播放 /// 异步加载音效 /// /// 声音的预设名字(不包括前缀路径名) /// 延迟播放 单位秒 /// 音量 /// 是否循环播放 /// /// 是否强制重头播放 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 LoadSound(this SoundComponent self, string soundName) { if (!SoundComponent.abSounds.ContainsKey(soundName) || SoundComponent.abSounds[soundName] == null) { var prefab = await YooAssetComponent.Instance.LoadAssetAsync("Sound_"+soundName); SoundComponent.abSounds.Add(soundName, GameObject.Instantiate(prefab).GetComponent()); 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); } } /// /// 停止并销毁声音 /// /// 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(); } } /// /// 暂停声音 /// /// public static void Pause(this SoundComponent self, string clipName) { SoundData data = self.GetAudioSource(clipName); if (null != data) { data.IsPause = true; data.audio.Pause(); } } /// /// 继续播放 /// /// public static void Resume(this SoundComponent self, string clipName) { SoundData data = self.GetAudioSource(clipName); if (null != data) { data.IsPause = false; data.audio.UnPause(); } } /// /// 销毁所有声音 /// 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(); } } }