From 91f1b18771db9cb8c9e615d7c35c1782cc4ccfaf Mon Sep 17 00:00:00 2001 From: Oliver Wong Date: Thu, 16 Apr 2026 14:39:58 +0800 Subject: [PATCH] feat: add PlayOnTrigger for music-synced audio playback - Add PlayOnTrigger method to AudioSystem for scheduling audio playback on music sync events (beat/bar/grid) - Rename ButtonInvoker to SetStateBind for better clarity - Update PlaySoundBind to support both direct playback and trigger-based playback with callback flags - Add CallbackFlags enum (MusicSyncBeat, MusicSyncBar, MusicSyncGrid) - Update Metronome demo to use new callback flag naming convention - Add test audio file sfx_notice_test.wav - Update scene UI to demonstrate PlayOnTrigger functionality --- Assets/Resources/AudioData/AudioObject.bytes | Bin 6590 -> 6668 bytes Assets/Resources/Audios/sfx_notice_test.wav | 3 + .../Resources/Audios/sfx_notice_test.wav.meta | 23 ++++ Assets/Scenes/SampleScene.unity | 125 ++---------------- .../Audio/Generated/AudioObjectDefinitions.cs | 1 + .../OCES/Audio/HandWritten/AudioSystem.cs | 43 ++++++ .../HandWritten/HandWrittenDefinitions.cs | 7 +- Assets/Scripts/OCES/Metronome.cs | 10 +- Assets/Scripts/OCES/PlaySoundBind.cs | 15 ++- .../{ButtonInvoker.cs => SetStateBind.cs} | 2 +- ...onInvoker.cs.meta => SetStateBind.cs.meta} | 0 11 files changed, 102 insertions(+), 127 deletions(-) create mode 100644 Assets/Resources/Audios/sfx_notice_test.wav create mode 100644 Assets/Resources/Audios/sfx_notice_test.wav.meta rename Assets/Scripts/OCES/{ButtonInvoker.cs => SetStateBind.cs} (92%) rename Assets/Scripts/OCES/{ButtonInvoker.cs.meta => SetStateBind.cs.meta} (100%) diff --git a/Assets/Resources/AudioData/AudioObject.bytes b/Assets/Resources/AudioData/AudioObject.bytes index fd3a83e7f03da4d03c6e8ff21f99a0cdab7c1fbb..59bfffbe7e7cdd9e604feb07f9125ef5617f63b8 100644 GIT binary patch delta 39 tcmdmI++)J%zL9aSq=Y*I0|O%v^B1R8#OLLgWG1J^m!uY#Ojcww0|3 AmbiguousNames = new() diff --git a/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs b/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs index fc0312f..0088bca 100644 --- a/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs +++ b/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs @@ -127,6 +127,49 @@ namespace OCES.Audio ActiveStates = this.m_musicSystem.ActiveStates; } + public void PlayOnTrigger(uint audioId, CallbackFlags callbackFlags) + { + Action callback = null; + callback = (id) => + { + // 播放音效 + Play(audioId); + + // 取消订阅,确保只触发一次 + switch (callbackFlags) + { + case CallbackFlags.MusicSyncBeat: + OnBeat -= callback; + break; + case CallbackFlags.MusicSyncBar: + OnBar -= callback; + break; + case CallbackFlags.MusicSyncGrid: + OnGrid -= callback; + break; + } + }; + + // 订阅对应的事件 + switch (callbackFlags) + { + case CallbackFlags.MusicSyncBeat: + OnBeat += callback; + break; + case CallbackFlags.MusicSyncBar: + OnBar += callback; + break; + case CallbackFlags.MusicSyncGrid: + OnGrid += callback; + break; + + default: + Debug.LogWarning($"[AudioSystem] Unknown callback flag '{callbackFlags}'." + + $"Audio Container with ID {audioId} will be ignored."); + break; + } + } + // ───────────────────────────────────────────── // 初始化 // ───────────────────────────────────────────── diff --git a/Assets/Scripts/OCES/Audio/HandWritten/HandWrittenDefinitions.cs b/Assets/Scripts/OCES/Audio/HandWritten/HandWrittenDefinitions.cs index e361d5a..dd7e3be 100644 --- a/Assets/Scripts/OCES/Audio/HandWritten/HandWrittenDefinitions.cs +++ b/Assets/Scripts/OCES/Audio/HandWritten/HandWrittenDefinitions.cs @@ -86,9 +86,10 @@ namespace OCES.Audio public partial class MusicPath : IPathEntry { } public partial class AmbiencePath : IPathEntry { } - public class SwitchEntry + public enum CallbackFlags { - public uint SwitchValue; - public uint AudioObjectId; + MusicSyncBeat = 1, + MusicSyncBar = 2, + MusicSyncGrid = 3, } } diff --git a/Assets/Scripts/OCES/Metronome.cs b/Assets/Scripts/OCES/Metronome.cs index b495ae9..402d5d8 100644 --- a/Assets/Scripts/OCES/Metronome.cs +++ b/Assets/Scripts/OCES/Metronome.cs @@ -3,6 +3,10 @@ using UnityEngine; namespace OCES { + /// + /// Drag this component to any game object. + /// Then you will get a metronome :) + /// public class Metronome : MonoBehaviour { void Start() @@ -10,17 +14,17 @@ namespace OCES AudioSystem.Instance.OnBeat += u => { AudioSystem.Instance.Play(52); - Debug.Log($"Container {u} is OnBeat"); + Debug.Log($"Container {u} is MusicSyncBeat"); }; AudioSystem.Instance.OnBar += u => { AudioSystem.Instance.Play(53); - Debug.Log($"Container {u} is OnBar"); + Debug.Log($"Container {u} is MusicSyncBar"); }; AudioSystem.Instance.OnGrid += u => { AudioSystem.Instance.Play(54); - Debug.Log($"Container {u} is OnGrid"); + Debug.Log($"Container {u} is MusicSyncGrid"); }; } } diff --git a/Assets/Scripts/OCES/PlaySoundBind.cs b/Assets/Scripts/OCES/PlaySoundBind.cs index feffb87..bade47a 100644 --- a/Assets/Scripts/OCES/PlaySoundBind.cs +++ b/Assets/Scripts/OCES/PlaySoundBind.cs @@ -2,16 +2,23 @@ using System.Collections; using System.Collections.Generic; using OCES.Audio; using UnityEngine; +using UnityEngine.Serialization; using UnityEngine.UI; public class PlaySoundBind : MonoBehaviour { - + public CallbackFlags callbackFlags; public InputField inputField; - public void OnButtonPressed() + public void PlaySound() { - uint.TryParse(this.inputField.text, out uint hapticId); - AudioSystem.Instance.Play(hapticId); + uint.TryParse(this.inputField.text, out uint audioId); + AudioSystem.Instance.Play(audioId); + } + + public void PlaySoundOnTrigger() + { + uint.TryParse(this.inputField.text, out uint audioId); + AudioSystem.Instance.PlayOnTrigger(audioId, this.callbackFlags); } } diff --git a/Assets/Scripts/OCES/ButtonInvoker.cs b/Assets/Scripts/OCES/SetStateBind.cs similarity index 92% rename from Assets/Scripts/OCES/ButtonInvoker.cs rename to Assets/Scripts/OCES/SetStateBind.cs index 5a4acd0..5d50705 100644 --- a/Assets/Scripts/OCES/ButtonInvoker.cs +++ b/Assets/Scripts/OCES/SetStateBind.cs @@ -5,7 +5,7 @@ using UnityEngine.Audio; namespace OCES { - public class ButtonInvoker : MonoBehaviour + public class SetStateBind : MonoBehaviour { public GameState targetGameState; public bool enableLowpass; diff --git a/Assets/Scripts/OCES/ButtonInvoker.cs.meta b/Assets/Scripts/OCES/SetStateBind.cs.meta similarity index 100% rename from Assets/Scripts/OCES/ButtonInvoker.cs.meta rename to Assets/Scripts/OCES/SetStateBind.cs.meta