feat: Add haptic system integration and audio test UI

- Add new audio assets and PlaySoundBind script for testing audio playback via UI input field.
- Implement haptic feedback integration in SfxSystem and fix initialization timing in HapticSystem.
- Update project settings with correct Android target architecture.
- Adjust DSP buffer size and enable development build debug logging.
This commit is contained in:
2026-04-14 10:18:34 +08:00
parent d8a787d9ce
commit 340b52e6b4
15 changed files with 864 additions and 34 deletions
@@ -175,7 +175,7 @@ namespace OCES.Audio
// ── 启动默认音乐与环境音 ──
// 触发一次初始状态,让音乐系统从默认状态开始匹配
SetState(GameState.Home);
//SetState(GameState.Home);
}
}
@@ -6,7 +6,7 @@ using UnityEngine.UI;
namespace OCES.Audio.Editor
{
#if UNITY_EDITOR
#if UNITY_EDITOR || DEVELOPMENT_BUILD
public sealed class DebugInfoCollector : MonoBehaviour
{
@@ -3,6 +3,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using OCES.Audio.HandWritten;
using OCES.Haptic;
using UnityEngine;
using UnityEngine.Audio;
@@ -260,6 +261,7 @@ namespace OCES.Audio
this.m_pool.ReturnToPool(source.gameObject);
//Debug.Log($"[Container - Continuous] 协程正常结束: {audioObject.Name[0]}");
// TryStopHaptic(audioObject.Haptic);
yield break;
}
}
@@ -371,6 +373,15 @@ namespace OCES.Audio
IncrementClipCount(activeSound.AudioObject.Id);
}
if (activeSound.AudioObject.ContainerType == ContainerType.Blend)
{
Debug.LogWarning($"[Haptic System] Blend container {activeSound.AudioObject.Id} should not have haptic feedback!");
}
else
{
TryStartHaptic(activeSound);
}
activeSound.Coroutine = StartCoroutine(RemoveWhenFinished(activeSound));
}
@@ -446,7 +457,7 @@ namespace OCES.Audio
{
ContainerType.Random => m_containerSelector.PickShuffleIndex(audioObject),
ContainerType.Sequence => m_containerSelector.GetNextSequenceIndex(audioObject),
_ => 0
_ => 0,
};
if (!SetupSource(sourceSingle, active, index))
@@ -477,6 +488,8 @@ namespace OCES.Audio
DecrementClipCount(active.AudioObject.Id);
this.m_activeSounds.Remove(active);
// TryStopHaptic(active.AudioObject.Haptic);
this.m_pool.ReturnToPool(active.Source.gameObject);
}
@@ -498,8 +511,21 @@ namespace OCES.Audio
DecrementClipCount(active.AudioObject.Id);
this.m_activeSounds.Remove(active);
this.m_pool.ReturnToPool(active.Source.gameObject);
// TryStopHaptic(active.AudioObject.Haptic);
}
static void TryStartHaptic(ActiveSound active)
{
uint hapticId = active.AudioObject.Haptic;
if (hapticId == 0) return;
HapticSystem.Instance.Play(hapticId, isDirectCall: false);
}
static void TryStopHaptic(uint hapticId)
{
HapticSystem.Instance.Stop(hapticId);
}
}
@@ -10,9 +10,9 @@ namespace OCES.Haptic
{
public static HapticSystem Instance {get; private set;}
[NonSerialized]
public bool IsHapticSupported = DeviceCapabilities.isVersionSupported;
public bool IsHapticSupported;
[NonSerialized]
public bool IsMeetsAdvanceRequirements = DeviceCapabilities.meetsAdvancedRequirements;
public bool IsMeetsAdvanceRequirements;
HapticObjectConfig m_hapticObjects;
const string k_hapticConfigPath = "HapticData/";
@@ -96,7 +96,7 @@ namespace OCES.Haptic
}
public void Stop()
public void Stop(uint? hapticId = null)
{
HapticController.Stop();
}
@@ -112,6 +112,8 @@ namespace OCES.Haptic
DontDestroyOnLoad(gameObject);
this.m_hapticObjects = HapticConfigLoader.Load<HapticObjectConfig>(k_hapticConfigPath + "HapticObject");
this.IsHapticSupported = DeviceCapabilities.isVersionSupported;
this.IsMeetsAdvanceRequirements = DeviceCapabilities.meetsAdvancedRequirements;
}
static HapticClip GetHapticClip(HapticObject hapticObject)
+17
View File
@@ -0,0 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using OCES.Audio;
using UnityEngine;
using UnityEngine.UI;
public class PlaySoundBind : MonoBehaviour
{
public InputField inputField;
public void OnButtonPressed()
{
uint.TryParse(this.inputField.text, out uint hapticId);
AudioSystem.Instance.Play(hapticId);
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3bdbaddf2c05142e19686a9a82ef92c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: