UFL6-3——音效管理模块优化
优化频繁创建删除音效组件
目前我们音效管理器中的音效组件会频繁的创建和删除
这样会产生大量的内存垃圾,并且频繁创建对象也会带来性能消耗
因此我们可以利用缓存池对其进行优化
按照之前实现的缓存池要求,在场景上创建一个挂载音效源的对象,然后挂载一个poolObj脚本,然后设置最大存在数量maxNum
因此,我们不再需要一个专门挂载音效源的对象,而是转为使用缓存池创建挂载音效源的对象
播放音效时,从缓存池内取出音效对象,停止播放音效(因为该音效可能正在播放其他音效),设置音效切片
停止播放或者帧更新检测播放停止时,清空关联的音效切片,从管理列表内移除,将音效对象压回对象池内,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
   |  private List<AudioSource> soundList = new List<AudioSource>();
  private MusicManager()  {          MonoManager.Instance.AddFixedUpdateListener(Update); }
  private void Update() {     if (!soundIsPlay)         return;          for (int i = soundList.Count - 1; i >= 0; i--)     {         if (!soundList[i].isPlaying)         {                          soundList[i].clip = null;             PoolManager.Instance.PushObj(soundList[i].gameObject);             soundList.RemoveAt(i);         }     } }
  public void PlaySound(string name, bool isLoop = false, bool isSync = false, UnityAction<AudioSource> callBack = null) {          ABResManager.Instance.LoadResAsync<AudioClip>("sound", name, (clip) =>     {                  AudioSource source = PoolManager.Instance.GetObj("Sound/soundObj").GetComponent<AudioSource>();                  source.Stop();         source.clip = clip;         source.loop = isLoop;         source.volume = soundVolume;         source.Play();                  if (!soundList.Contains(source))             soundList.Add(source);                  callBack?.Invoke(source);     }, isSync); }
  public void StopSound(AudioSource source) {     if (soundList.Contains(source))     {         source.Stop();         soundList.Remove(source);                  source.clip = null;         PoolManager.Instance.PushObj(source.gameObject);     } }
 
  | 
 
优化3D音效问题
由于我们使用了缓存池,因此AudioSource依附的将会是一个个独立的游戏对象,而3D音效主要考虑的问题是:
- 音效依附在对象上跟随对象移动
 
- 音效中3D相关参数的设置
 
如果你想要使用3D音效,那么只需要获取到音效组件和它依附的对象就可以迎刃而解了
- 获取音效组件依附的对象,改变它的父对象,设置它的位置,音效便可以跟随对象移动
 
- 获取音效组件改变其中的3D音效相关参数即可完成相关设置
 
1 2 3 4 5 6 7 8 9 10 11
   | if (GUILayout.Button("播放音效")) {     MusicManager.Instance.PlaySound("sound_1", false, false, (source) =>     {         GameObject soundObj = source.gameObject;         source.gameObject.transform.SetParent(soundObj.transform);         source.spatialBlend = 1f;                              }); }
  | 
 
提供清除所有音效的方法
目前过场景时,音效相关对象会被自动的删除,但是音效管理器中我们的容器还占着引用,我们应该提供方法清空容器
值得一提的是,该方法必须要在清空缓存池前去调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | 
 
  public void ClearSound() {     for (int i = 0; i < soundList.Count; i++)     {         soundList[i].Stop();         soundList[i].clip = null;         PoolManager.Instance.PushObj(soundList[i].gameObject);     }          soundList.Clear(); }
 
  | 
 
具体代码