82 lines
2.8 KiB
C#
82 lines
2.8 KiB
C#
using UnityEngine;
|
||
using BaseGames.Core.Events;
|
||
using BaseGames.Combat;
|
||
|
||
namespace BaseGames.Audio
|
||
{
|
||
/// <summary>
|
||
/// 订阅战斗/死亡事件,通过 GlobalSFXPlayer 播放对应 AudioEventSO 音效。
|
||
/// 挂载在 Persistent 场景的 [Systems] GameObject 上。
|
||
/// 使用 AudioEventSO 替代裸 AudioClip,支持随机音量 / 音调 / 多片段。
|
||
/// </summary>
|
||
public class CombatSFXController : MonoBehaviour
|
||
{
|
||
[Header("Event Channels")]
|
||
[SerializeField] private HitConfirmedEventChannelSO _onHitConfirmed;
|
||
[SerializeField] private VoidEventChannelSO _onPlayerDied;
|
||
|
||
[Header("Default Hit SFX")]
|
||
[SerializeField] private AudioEventSO _defaultHitSFX;
|
||
|
||
[Header("Per-Type Hit SFX (optional, overrides default)")]
|
||
[SerializeField] private AudioEventSO _sparkHitSFX;
|
||
[SerializeField] private AudioEventSO _slashHitSFX;
|
||
[SerializeField] private AudioEventSO _bloodHitSFX;
|
||
[SerializeField] private AudioEventSO _magicHitSFX;
|
||
[SerializeField] private AudioEventSO _heavyHitSFX;
|
||
[SerializeField] private AudioEventSO _critHitSFX;
|
||
[SerializeField] private AudioEventSO _parryHitSFX;
|
||
[SerializeField] private AudioEventSO _fireHitSFX;
|
||
[SerializeField] private AudioEventSO _iceHitSFX;
|
||
|
||
[Header("Death SFX")]
|
||
[SerializeField] private AudioEventSO _playerDeathSFX;
|
||
|
||
private readonly CompositeDisposable _subs = new();
|
||
|
||
private void OnEnable()
|
||
{
|
||
_onHitConfirmed?.Subscribe(HandleHit).AddTo(_subs);
|
||
_onPlayerDied?.Subscribe(HandlePlayerDied).AddTo(_subs);
|
||
}
|
||
|
||
private void OnDisable()
|
||
{
|
||
_subs.Clear();
|
||
}
|
||
|
||
private void HandleHit(HitInfo info)
|
||
{
|
||
AudioEventSO sfx = ResolveHitSFX(info.DamageInfo.FxType);
|
||
if (sfx == null) return;
|
||
|
||
GlobalSFXPlayer.Play(sfx, info.HitPoint);
|
||
}
|
||
|
||
private void HandlePlayerDied()
|
||
{
|
||
if (_playerDeathSFX == null) return;
|
||
GlobalSFXPlayer.Play(_playerDeathSFX);
|
||
}
|
||
|
||
private AudioEventSO ResolveHitSFX(HitFxType fxType)
|
||
{
|
||
AudioEventSO 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;
|
||
}
|
||
}
|
||
}
|