using System; using System.Collections.Generic; using UnityEngine; namespace OCES.Audio { /// /// 音乐与环境音系统。由 AudioSystem 持有并初始化。 /// 对外只暴露 OnStateChanged,由 AudioSystem.SetState 转发调用。 /// class MusicSystem : MonoBehaviour { MusicStateRouter m_stateRouter; MusicChannelPlayer m_musicChannel; AmbienceChannelPlayer m_ambienceChannel; internal event Action OnBeat; internal event Action OnBar; internal event Action OnGrid; // 记录上一次两个通道各自匹配到的 PathId,用于查 Transition 表 uint m_lastMusicPathId; uint m_lastAmbiencePathId; internal IReadOnlyDictionary ActiveStates { get { return this.m_stateRouter.ActiveStates; } } internal void Initialize( MusicSegmentConfig segments, MusicContainerConfig containers, MusicPathConfig musicPaths, AmbiencePathConfig ambiencePaths, MusicTransitionConfig musicTransitions, AmbienceTransitionConfig ambienceTransitions, AudioSourcePool musicPool, AudioSourcePool ambiencePool) { MusicContainerPlayer musicContainerPlayer = new(containers, segments, musicPool, this); MusicContainerPlayer ambientContainerPlayer = new(containers, segments, ambiencePool, this); this.m_stateRouter = new MusicStateRouter(musicPaths, ambiencePaths); this.m_musicChannel = new MusicChannelPlayer( containers, musicTransitions, musicContainerPlayer, this, id => OnBeat?.Invoke(id), id => OnBar?.Invoke(id), id => OnGrid?.Invoke(id)); this.m_ambienceChannel = new AmbienceChannelPlayer(ambienceTransitions, ambientContainerPlayer, this); } /// /// 由 AudioSystem.SetState 调用,更新状态并驱动两个通道切换。 /// internal void OnStateChanged(TEnum state) where TEnum : Enum { this.m_stateRouter.SetState( state, out uint musicContainerId, out uint ambienceContainerId); uint newMusicPathId = this.m_stateRouter.LastMusicPathId; uint newAmbiencePathId = this.m_stateRouter.LastAmbiencePathId; this.m_musicChannel.SwitchTo(musicContainerId, this.m_lastMusicPathId, newMusicPathId); this.m_ambienceChannel.SwitchTo(ambienceContainerId, this.m_lastAmbiencePathId, newAmbiencePathId); this.m_lastMusicPathId = newMusicPathId; this.m_lastAmbiencePathId = newAmbiencePathId; } } }