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
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fd46c0791afd4242a0ac5913b1be63b
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 7
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 0
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1298,7 +1298,7 @@ MonoBehaviour:
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: PlaySound Direct
|
||||
m_Text: PlaySound OnTrigger
|
||||
--- !u!222 &1193187745
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -1319,7 +1319,6 @@ GameObject:
|
||||
- component: {fileID: 1371927796}
|
||||
- component: {fileID: 1371927795}
|
||||
- component: {fileID: 1371927794}
|
||||
- component: {fileID: 1371927798}
|
||||
- component: {fileID: 1371927797}
|
||||
m_Layer: 5
|
||||
m_Name: PlaySoundDirect
|
||||
@@ -1327,7 +1326,7 @@ GameObject:
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1371927793
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -1343,9 +1342,9 @@ RectTransform:
|
||||
- {fileID: 1193187743}
|
||||
m_Father: {fileID: 1667985901}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 150, y: -608.3334}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 160, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1371927794
|
||||
@@ -1392,21 +1391,9 @@ MonoBehaviour:
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 1371927798}
|
||||
m_TargetAssemblyTypeName: UnityEngine.AudioSource, UnityEngine
|
||||
m_MethodName: Play
|
||||
m_Mode: 1
|
||||
m_Arguments:
|
||||
m_ObjectArgument: {fileID: 0}
|
||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||
m_IntArgument: 0
|
||||
m_FloatArgument: 0
|
||||
m_StringArgument:
|
||||
m_BoolArgument: 0
|
||||
m_CallState: 2
|
||||
- m_Target: {fileID: 1371927797}
|
||||
m_TargetAssemblyTypeName: PlaySoundBind, Assembly-CSharp
|
||||
m_MethodName: OnButtonPressed
|
||||
m_MethodName: PlaySoundOnTrigger
|
||||
m_Mode: 1
|
||||
m_Arguments:
|
||||
m_ObjectArgument: {fileID: 0}
|
||||
@@ -1466,103 +1453,8 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 3bdbaddf2c05142e19686a9a82ef92c3, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
callbackFlags: 2
|
||||
inputField: {fileID: 1490886059}
|
||||
--- !u!82 &1371927798
|
||||
AudioSource:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1371927792}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 4
|
||||
OutputAudioMixerGroup: {fileID: -1744738308437188463, guid: 11793d92750e64286bcdd6a61eeec520, type: 2}
|
||||
m_audioClip: {fileID: 8300000, guid: 95f3e694b4c5b4892871f69fd96b4b7f, type: 3}
|
||||
m_PlayOnAwake: 0
|
||||
m_Volume: 1
|
||||
m_Pitch: 1
|
||||
Loop: 0
|
||||
Mute: 0
|
||||
Spatialize: 0
|
||||
SpatializePostEffects: 0
|
||||
Priority: 128
|
||||
DopplerLevel: 1
|
||||
MinDistance: 1
|
||||
MaxDistance: 500
|
||||
Pan2D: 0
|
||||
rolloffMode: 0
|
||||
BypassEffects: 0
|
||||
BypassListenerEffects: 0
|
||||
BypassReverbZones: 0
|
||||
rolloffCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
- serializedVersion: 3
|
||||
time: 1
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
panLevelCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
spreadCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
reverbZoneMixCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
--- !u!1 &1394234347
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -1649,7 +1541,7 @@ MonoBehaviour:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 1394234352}
|
||||
m_TargetAssemblyTypeName: PlaySoundBind, Assembly-CSharp
|
||||
m_MethodName: OnButtonPressed
|
||||
m_MethodName: PlaySound
|
||||
m_Mode: 1
|
||||
m_Arguments:
|
||||
m_ObjectArgument: {fileID: 0}
|
||||
@@ -1709,6 +1601,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 3bdbaddf2c05142e19686a9a82ef92c3, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
callbackFlags: 0
|
||||
inputField: {fileID: 1490886059}
|
||||
--- !u!1 &1490886057
|
||||
GameObject:
|
||||
|
||||
@@ -103,6 +103,7 @@ public static class AudioObjectDefinitions
|
||||
{ "au_sfx_ui_button_corePlay_clear_cloud1", 70 },
|
||||
{ "au_sfx_ui_button_corePlay_clear_cloud2", 70 },
|
||||
{ "au_sfx_ui_button_corePlay_clear_cloud3", 70 },
|
||||
{ "sfx_notice_test", 71 },
|
||||
};
|
||||
|
||||
public static readonly HashSet<string> AmbiguousNames = new()
|
||||
|
||||
@@ -127,6 +127,49 @@ namespace OCES.Audio
|
||||
ActiveStates = this.m_musicSystem.ActiveStates;
|
||||
}
|
||||
|
||||
public void PlayOnTrigger(uint audioId, CallbackFlags callbackFlags)
|
||||
{
|
||||
Action<uint> 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;
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────
|
||||
// 初始化
|
||||
// ─────────────────────────────────────────────
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@ using UnityEngine;
|
||||
|
||||
namespace OCES
|
||||
{
|
||||
/// <summary>
|
||||
/// Drag this component to any game object.
|
||||
/// Then you will get a metronome :)
|
||||
/// </summary>
|
||||
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");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ using UnityEngine.Audio;
|
||||
|
||||
namespace OCES
|
||||
{
|
||||
public class ButtonInvoker : MonoBehaviour
|
||||
public class SetStateBind : MonoBehaviour
|
||||
{
|
||||
public GameState targetGameState;
|
||||
public bool enableLowpass;
|
||||
Reference in New Issue
Block a user