diff --git a/Assets/Resources/AudioData/AudioObject.bytes b/Assets/Resources/AudioData/AudioObject.bytes index e8ae421..330a5f6 100644 Binary files a/Assets/Resources/AudioData/AudioObject.bytes and b/Assets/Resources/AudioData/AudioObject.bytes differ diff --git a/Assets/Resources/AudioData/MusicTransition.bytes b/Assets/Resources/AudioData/MusicTransition.bytes index 7948618..a18a9fc 100644 Binary files a/Assets/Resources/AudioData/MusicTransition.bytes and b/Assets/Resources/AudioData/MusicTransition.bytes differ diff --git a/Assets/Resources/Audios/Master.mixer b/Assets/Resources/Audios/Master.mixer index 7a1cca0..eea34c9 100644 --- a/Assets/Resources/Audios/Master.mixer +++ b/Assets/Resources/Audios/Master.mixer @@ -110,6 +110,33 @@ AudioMixerEffectController: m_SendTarget: {fileID: 0} m_EnableWetMix: 0 m_Bypass: 0 +--- !u!245 &-4895586400299347591 +AudioMixerSnapshotController: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: LowpassAll + m_AudioMixer: {fileID: 24100000} + m_SnapshotID: 78be188d012d34dfdaed6b11404dd75d + m_FloatValues: + d66e5a701962f484baca61ea5f29bab9: -0.27209902 + 32004492d90c94a6b89f5caf3841e0a6: 2000 + 19038a83c76cc4d6a879eac8c024aae0: 0 + d25d07d33c23743818a83a02bdf2d50f: -0.27209944 + 9b4461d5598de4602b001fc9d34f76a7: 22000 + 9d40f8f6b3cb746b880ab3eef4d4d147: 0 + 8a546ef62c9da440fab526ddd396adb0: 22000 + 6194c288be1cd4cef9afabff865f1674: 0 + 33063898bc8ef442eaeaf76f1829a2f5: -0.39762527 + 676d0e59581a446dfb975928b4b3a4ea: 2827 + 0053647b950eb4d8abf883dc07d6b4ef: 1 + bd3c2e9d76bd5446ab3f0200f79c27fb: -0.16685188 + 47b8a12e60a1c4cf18d0d0c28f12866d: 440 + f9b2498f18d9c4346b50d00374df58fc: -0.08374829 + c31161cf8dc3a48478fe71156b990b48: 1333 + d171c8cff3d664001b51b62c1b77ab53: 0 + m_TransitionOverrides: {} --- !u!244 &-3976313734993682518 AudioMixerEffectController: m_ObjectHideFlags: 3 @@ -138,6 +165,25 @@ AudioMixerEffectController: m_SendTarget: {fileID: 0} m_EnableWetMix: 0 m_Bypass: 0 +--- !u!243 &-2632954964847484640 +AudioMixerGroupController: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: SFX_Accent + m_AudioMixer: {fileID: 24100000} + m_GroupID: 9e4fd853e217e4549889f3e0b3ea96a1 + m_Children: [] + m_Volume: 15cd4cd29b1a64dacb39ca2eda4de378 + m_Pitch: eacb2d41d6e344d7089f05d7f8af177f + m_Send: 00000000000000000000000000000000 + m_Effects: + - {fileID: 3438428155425117149} + m_UserColorIndex: 0 + m_Mute: 0 + m_Solo: 0 + m_BypassEffects: 0 --- !u!244 &-1981897495521119487 AudioMixerEffectController: m_ObjectHideFlags: 3 @@ -152,6 +198,20 @@ AudioMixerEffectController: m_SendTarget: {fileID: 0} m_EnableWetMix: 0 m_Bypass: 0 +--- !u!244 &-1981299437118637510 +AudioMixerEffectController: + m_ObjectHideFlags: 3 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_EffectID: 4dd176fef55324e63a21883b5cf9a7d6 + m_EffectName: Attenuation + m_MixLevel: 1b8fc276669da411b916a4fdde063ba0 + m_Parameters: [] + m_SendTarget: {fileID: 0} + m_EnableWetMix: 0 + m_Bypass: 0 --- !u!243 &-1744738308437188463 AudioMixerGroupController: m_ObjectHideFlags: 0 @@ -183,12 +243,13 @@ AudioMixerController: m_MasterGroup: {fileID: 24300002} m_Snapshots: - {fileID: 24500006} + - {fileID: -4895586400299347591} m_StartSnapshot: {fileID: 24500006} m_SuspendThreshold: -80 m_EnableSuspend: 1 m_UpdateMode: 0 m_ExposedParameters: - - guid: 676d0e59581a446dfb975928b4b3a4ea + - guid: 9b4461d5598de4602b001fc9d34f76a7 name: LowpassFreq m_AudioMixerGroupViews: - guids: @@ -197,9 +258,11 @@ AudioMixerController: - fbb492056217044b38d9101862ddc436 - 5e41f800db72248f5afd2396c0554245 - bd6166e85bbd34672815848ab982ee14 + - 9e4fd853e217e4549889f3e0b3ea96a1 + - 5aea325100740470084872588978f2de name: View m_CurrentViewIndex: 0 - m_TargetSnapshot: {fileID: 24500006} + m_TargetSnapshot: {fileID: -4895586400299347591} --- !u!243 &24300002 AudioMixerGroupController: m_ObjectHideFlags: 0 @@ -210,15 +273,13 @@ AudioMixerGroupController: m_AudioMixer: {fileID: 24100000} m_GroupID: 3ef0a681afabf403eae42ddfe3bed37e m_Children: - - {fileID: -1744738308437188463} - - {fileID: 6676643924165511292} - - {fileID: -8446907912838507648} + - {fileID: -2632954964847484640} + - {fileID: 4559115090182944919} m_Volume: d25d07d33c23743818a83a02bdf2d50f m_Pitch: 742836698fec2460687f7c5098a06cfe m_Send: 00000000000000000000000000000000 m_Effects: - {fileID: 24400004} - - {fileID: 2973470794043586341} m_UserColorIndex: 0 m_Mute: 0 m_Solo: 0 @@ -247,8 +308,10 @@ AudioMixerSnapshotController: m_AudioMixer: {fileID: 24100000} m_SnapshotID: 63ccd225cc2574a849ba6b48bc35a1b4 m_FloatValues: + bd38229261bcb45f483ee4bfa0e04042: 22000 32004492d90c94a6b89f5caf3841e0a6: 2000 19038a83c76cc4d6a879eac8c024aae0: 0 + 22a117c38c88245258b6ce9f59a19f58: 22000 d25d07d33c23743818a83a02bdf2d50f: -0.27209944 9d40f8f6b3cb746b880ab3eef4d4d147: 0 6194c288be1cd4cef9afabff865f1674: 0 @@ -258,6 +321,22 @@ AudioMixerSnapshotController: c31161cf8dc3a48478fe71156b990b48: 1333 d171c8cff3d664001b51b62c1b77ab53: 0 m_TransitionOverrides: {} +--- !u!244 &1357487930948756019 +AudioMixerEffectController: + m_ObjectHideFlags: 3 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_EffectID: aa8032429f01e4deebabf55a851befc1 + m_EffectName: Lowpass Simple + m_MixLevel: c6fa43abc9ff74653ad069878a34a22c + m_Parameters: + - m_ParameterName: Cutoff freq + m_GUID: 9b4461d5598de4602b001fc9d34f76a7 + m_SendTarget: {fileID: 0} + m_EnableWetMix: 0 + m_Bypass: 0 --- !u!244 &2280317501892162058 AudioMixerEffectController: m_ObjectHideFlags: 3 @@ -272,22 +351,43 @@ AudioMixerEffectController: m_SendTarget: {fileID: 0} m_EnableWetMix: 0 m_Bypass: 0 ---- !u!244 &2973470794043586341 +--- !u!244 &3438428155425117149 AudioMixerEffectController: m_ObjectHideFlags: 3 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: - m_EffectID: cb0e61261c99c4cf9b060cbe0a07b0a7 - m_EffectName: Lowpass Simple - m_MixLevel: 92d4b33f017f9446d9568dfb1edf0513 - m_Parameters: - - m_ParameterName: Cutoff freq - m_GUID: 676d0e59581a446dfb975928b4b3a4ea + m_EffectID: 4eee86d0195f84d38af0f35a02daeb94 + m_EffectName: Attenuation + m_MixLevel: 55868e257aa82426f9159f2cea706660 + m_Parameters: [] m_SendTarget: {fileID: 0} m_EnableWetMix: 0 m_Bypass: 0 +--- !u!243 &4559115090182944919 +AudioMixerGroupController: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Regular + m_AudioMixer: {fileID: 24100000} + m_GroupID: 5aea325100740470084872588978f2de + m_Children: + - {fileID: -8446907912838507648} + - {fileID: 6676643924165511292} + - {fileID: -1744738308437188463} + m_Volume: badd11e23656942dd82b7998948a7579 + m_Pitch: ffb7c42cb170043789e682bbb8ba41bb + m_Send: 00000000000000000000000000000000 + m_Effects: + - {fileID: -1981299437118637510} + - {fileID: 1357487930948756019} + m_UserColorIndex: 0 + m_Mute: 0 + m_Solo: 0 + m_BypassEffects: 0 --- !u!244 &5392472840872469294 AudioMixerEffectController: m_ObjectHideFlags: 3 diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 93f3ca3..e3f8118 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -812,7 +812,19 @@ MonoBehaviour: m_TargetGraphic: {fileID: 876276285} m_OnClick: m_PersistentCalls: - m_Calls: [] + m_Calls: + - m_Target: {fileID: 2093584670} + m_TargetAssemblyTypeName: OCES.Audio.AudioSystem, Assembly-CSharp + m_MethodName: Play + m_Mode: 3 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 11 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 --- !u!114 &876276285 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/OCES/Audio/Generated/AudioObject.cs b/Assets/Scripts/OCES/Audio/Generated/AudioObject.cs index c1cd206..ee99a3f 100644 --- a/Assets/Scripts/OCES/Audio/Generated/AudioObject.cs +++ b/Assets/Scripts/OCES/Audio/Generated/AudioObject.cs @@ -44,6 +44,7 @@ public partial class AudioObject : IBinarySerializable /// 0 = SFX /// 1 = Muisc /// 2 = Voice + /// 3 = Accent /// public MixingType MixingType { get; set; } diff --git a/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs b/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs index 2814973..fa09d5d 100644 --- a/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs +++ b/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs @@ -14,7 +14,7 @@ namespace OCES.Audio const string k_audioConfigPath = "AudioData"; const string k_audioResourcePath = "Audios"; - AudioScheduler m_scheduler; + SfxSystem m_sfxSystem; MusicSystem m_musicSystem; AudioObjectConfig m_audioObjects; @@ -26,16 +26,18 @@ namespace OCES.Audio // 公开接口 // ───────────────────────────────────────────── - public void Play(uint audioId) + public void Play(uint audioId, Action onPlay = null) { AudioObject obj = this.m_audioObjects.QueryById(audioId); if (obj != null) - Play(obj); + { + Play(obj, onPlay); + } } - public void Play(AudioObject audioObject) + public void Play(AudioObject audioObject, Action onPlay = null) { - this.m_scheduler.TryPlay(audioObject); + this.m_sfxSystem.TryPlay(audioObject, onPlay); } public void Play(int audioId) @@ -126,10 +128,15 @@ namespace OCES.Audio this.m_mixer = Resources.Load("Audios/Master"); // ── SFX 调度器 ── - this.m_scheduler = gameObject.AddComponent(); + // AudioSystem.cs 中 + GameObject sfxPoolRoot = new("SfxSourcePool"); + sfxPoolRoot.transform.SetParent(transform, false); + AudioSourcePool sfxPool = new(sfxPoolRoot.transform); // 不传 mixer group,让 SfxSystem 自己设置 + this.m_sfxSystem = gameObject.AddComponent(); this.m_audioObjects = AudioConfigLoader.Load($"{k_audioConfigPath}/AudioObject"); this.m_groups = AudioConfigLoader.Load($"{k_audioConfigPath}/AudioGroup"); - this.m_scheduler.Initialize(this.m_groups, this.m_mixer); + this.m_sfxSystem.Initialize(this.m_groups, this.m_mixer, sfxPool); // 传入 pool + // ── 音乐与环境音系统 ── var segments = AudioConfigLoader.Load($"{k_audioConfigPath}/MusicSegment"); @@ -145,12 +152,12 @@ namespace OCES.Audio // AudioSourcePool 由 MusicSystem 独占一个子节点,与 SFX pool 隔离 GameObject musicPoolRoot = new("MusicSourcePool"); musicPoolRoot.transform.SetParent(transform, false); - AudioMixerGroup musicGroup = this.m_mixer.FindMatchingGroups("Master/Music")[0]; + AudioMixerGroup musicGroup = this.m_mixer.FindMatchingGroups("Master/Regular/Music")[0]; AudioSourcePool musicPool = new(musicPoolRoot.transform, musicGroup); GameObject ambiencePoolRoot = new("AmbienceSourcePool"); - musicPoolRoot.transform.SetParent(transform, false); - AudioMixerGroup ambienceGroup = this.m_mixer.FindMatchingGroups("Master/SFX/Ambience")[0]; + ambiencePoolRoot.transform.SetParent(transform, false); + AudioMixerGroup ambienceGroup = this.m_mixer.FindMatchingGroups("Master/Regular/SFX/Ambience")[0]; AudioSourcePool ambiencePool = new(ambiencePoolRoot.transform, ambienceGroup); this.m_musicSystem.Initialize( diff --git a/Assets/Scripts/OCES/Audio/HandWritten/HandWrittenDefinitions.cs b/Assets/Scripts/OCES/Audio/HandWritten/HandWrittenDefinitions.cs index 14cc56d..c24ea55 100644 --- a/Assets/Scripts/OCES/Audio/HandWritten/HandWrittenDefinitions.cs +++ b/Assets/Scripts/OCES/Audio/HandWritten/HandWrittenDefinitions.cs @@ -17,8 +17,8 @@ namespace OCES.Audio public enum MixingType { Sfx = 0, - Music, Voice, + Accented, } /// diff --git a/Assets/Scripts/OCES/Audio/HandWritten/AudioScheduler.cs b/Assets/Scripts/OCES/Audio/HandWritten/SfxSystem.cs similarity index 94% rename from Assets/Scripts/OCES/Audio/HandWritten/AudioScheduler.cs rename to Assets/Scripts/OCES/Audio/HandWritten/SfxSystem.cs index 379a97a..cd35e50 100644 --- a/Assets/Scripts/OCES/Audio/HandWritten/AudioScheduler.cs +++ b/Assets/Scripts/OCES/Audio/HandWritten/SfxSystem.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -7,9 +8,9 @@ using UnityEngine.Audio; namespace OCES.Audio { /// - /// 音频调度器 + /// 音效系统 /// - public class AudioScheduler : MonoBehaviour + public class SfxSystem : MonoBehaviour { public UnityEngine.UI.Text audioSystemTextBox; @@ -27,8 +28,8 @@ namespace OCES.Audio AudioGroupConfig m_groupConfig; AudioMixerGroup m_sfxGroup; - AudioMixerGroup m_musicGroup; AudioMixerGroup m_voiceGroup; + AudioMixerGroup m_accentSfxGroup; AudioSourcePool m_pool; AudioContainerSelector m_containerSelector; PitchStepResolver m_pitchStepResolver; @@ -50,7 +51,9 @@ namespace OCES.Audio void IncrementClipCount(uint id) { this.m_clipConcurrentCount[id] = GetClipCount(id) + 1; +#if UNITY_EDITOR Debug.Log($"{id} count added to {GetClipCount(id)}"); +#endif } void DecrementClipCount(uint id) @@ -64,18 +67,21 @@ namespace OCES.Audio // 初始化 // ───────────────────────────────────────────── - public void Initialize(AudioGroupConfig groups, AudioMixer mixer) + public void Initialize(AudioGroupConfig groups, AudioMixer mixer, AudioSourcePool pool) { this.m_groupConfig = groups; - this.m_pool = new AudioSourcePool(transform); + this.m_pool = pool; this.m_containerSelector = new AudioContainerSelector(); this.m_pitchStepResolver = new PitchStepResolver(); - AudioMixerGroup[] sfx = Find("Master/SFX"); + AudioMixerGroup[] sfx = Find("Master/Regular/SFX"); if (sfx.Length > 0) this.m_sfxGroup = sfx[0]; - AudioMixerGroup[] voice = Find("Master/Voice"); + AudioMixerGroup[] voice = Find("Master/Regular/Voice"); if (voice.Length > 0) this.m_voiceGroup = voice[0]; + AudioMixerGroup[] accentSfx = Find("Master/SFX_Accent"); + if (accentSfx.Length > 0) this.m_accentSfxGroup = accentSfx[0]; + return; AudioMixerGroup[] Find(string path) => mixer.FindMatchingGroups(path); @@ -85,7 +91,7 @@ namespace OCES.Audio // 节流 & 调度入口 // ───────────────────────────────────────────── - internal void TryPlay(AudioObject audioObject) + internal void TryPlay(AudioObject audioObject, Action onPlay = null) { double now = Time.realtimeSinceStartupAsDouble * 1000.0; @@ -169,6 +175,7 @@ namespace OCES.Audio float pitch = this.m_pitchStepResolver.ResolvePitch(audioObject, now); //算一下用不用变调 PlayNewSound(audioObject, pitch); this.m_lastPlayTime[audioObject.Id] = now; + onPlay?.Invoke(); } // ───────────────────────────────────────────── @@ -263,6 +270,7 @@ namespace OCES.Audio yield return new WaitForSeconds(audioObject.InitialDelay); if (!this.m_activeSounds.Contains(active)) yield break; + active.Pitch = pitch; ExecutePlay(active, isRegistered: true); } @@ -312,11 +320,21 @@ namespace OCES.Audio /// AudioMixerGroup GetMixerGroup(MixingType type) => type switch { - MixingType.Music => this.m_musicGroup, MixingType.Voice => this.m_voiceGroup, - _ => this.m_sfxGroup, + MixingType.Accented => this.m_accentSfxGroup, + _ => GetDefaultGroup(type), }; + AudioMixerGroup GetDefaultGroup(MixingType type) + { + if (type != MixingType.Sfx) + { + Debug.LogWarning($"[SfxSystem] Unrecognized MixingType: {type}, defaulting to SFX."); + } + + return this.m_sfxGroup; + } + bool SetupSource(AudioSource source, AudioObject audioObject, float pitch, int clipIndex = 0) { AudioClip clip = Resources.Load($"Audios/{audioObject.Name[clipIndex]}"); // TODO 抽象同一资源加载接口 diff --git a/Assets/Scripts/OCES/Audio/HandWritten/AudioScheduler.cs.meta b/Assets/Scripts/OCES/Audio/HandWritten/SfxSystem.cs.meta similarity index 100% rename from Assets/Scripts/OCES/Audio/HandWritten/AudioScheduler.cs.meta rename to Assets/Scripts/OCES/Audio/HandWritten/SfxSystem.cs.meta