86 lines
2.9 KiB
C#
86 lines
2.9 KiB
C#
using UnityEngine;
|
|
using BaseGames.Core.Events;
|
|
using BaseGames.Combat;
|
|
|
|
namespace BaseGames.Audio
|
|
{
|
|
/// <summary>
|
|
/// 订阅战斗/死亡事件,通过 AudioManager 播放对应 SFX。
|
|
/// 挂载在 Persistent 场景的 [Systems] GameObject 上。
|
|
/// </summary>
|
|
public class CombatSFXController : MonoBehaviour
|
|
{
|
|
[Header("Event Channels")]
|
|
[SerializeField] private HitConfirmedEventChannelSO _onHitConfirmed;
|
|
[SerializeField] private VoidEventChannelSO _onPlayerDied;
|
|
|
|
[Header("Default Hit SFX")]
|
|
[SerializeField] private AudioClip _defaultHitSFX;
|
|
|
|
[Header("Per-Type Hit SFX (optional, overrides default)")]
|
|
[SerializeField] private AudioClip _sparkHitSFX;
|
|
[SerializeField] private AudioClip _slashHitSFX;
|
|
[SerializeField] private AudioClip _bloodHitSFX;
|
|
[SerializeField] private AudioClip _magicHitSFX;
|
|
[SerializeField] private AudioClip _heavyHitSFX;
|
|
[SerializeField] private AudioClip _critHitSFX;
|
|
[SerializeField] private AudioClip _parryHitSFX;
|
|
[SerializeField] private AudioClip _fireHitSFX;
|
|
[SerializeField] private AudioClip _iceHitSFX;
|
|
|
|
[Header("Death SFX")]
|
|
[SerializeField] private AudioClip _playerDeathSFX;
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (_onHitConfirmed != null)
|
|
_onHitConfirmed.OnEventRaised += HandleHit;
|
|
|
|
if (_onPlayerDied != null)
|
|
_onPlayerDied.OnEventRaised += HandlePlayerDied;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (_onHitConfirmed != null)
|
|
_onHitConfirmed.OnEventRaised -= HandleHit;
|
|
|
|
if (_onPlayerDied != null)
|
|
_onPlayerDied.OnEventRaised -= HandlePlayerDied;
|
|
}
|
|
|
|
private void HandleHit(HitInfo info)
|
|
{
|
|
AudioClip clip = ResolveHitClip(info.DamageInfo.FxType);
|
|
if (clip == null) return;
|
|
|
|
AudioManager.Instance.PlaySFXAtPosition(clip, info.HitPoint);
|
|
}
|
|
|
|
private void HandlePlayerDied()
|
|
{
|
|
if (_playerDeathSFX == null) return;
|
|
AudioManager.Instance.PlaySFX(_playerDeathSFX);
|
|
}
|
|
|
|
private AudioClip ResolveHitClip(HitFxType fxType)
|
|
{
|
|
AudioClip perType = fxType switch
|
|
{
|
|
HitFxType.Spark => _sparkHitSFX,
|
|
HitFxType.Slash => _slashHitSFX,
|
|
HitFxType.Blood => _bloodHitSFX,
|
|
HitFxType.Magic => _magicHitSFX,
|
|
HitFxType.Heavy => _heavyHitSFX,
|
|
HitFxType.Crit => _critHitSFX,
|
|
HitFxType.Parry => _parryHitSFX,
|
|
HitFxType.Fire => _fireHitSFX,
|
|
HitFxType.Ice => _iceHitSFX,
|
|
_ => null
|
|
};
|
|
|
|
return perType != null ? perType : _defaultHitSFX;
|
|
}
|
|
}
|
|
}
|