摄像机区域的优化
This commit is contained in:
91
Assets/_Game/Scripts/Audio/FootstepSoundPlayer.cs
Normal file
91
Assets/_Game/Scripts/Audio/FootstepSoundPlayer.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using BaseGames.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BaseGames.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// 材质感知脚步声播放器。挂在玩家 GameObject 上,由 PlayerFeedback.PlayFootstep() 驱动。
|
||||
/// 每次触发时向下 OverlapCircle 探测脚下碰撞体,读取 FootstepMaterialMarker 决定材质,
|
||||
/// 再从 FootstepAudioConfigSO 随机选取 Clip 并叠加 Pitch 扰动后播放。
|
||||
/// 未探测到 Marker 时回落到 FootstepMaterial.Stone。
|
||||
/// </summary>
|
||||
public class FootstepSoundPlayer : MonoBehaviour
|
||||
{
|
||||
[Header("音效配置")]
|
||||
[SerializeField] private FootstepAudioConfigSO _config;
|
||||
|
||||
[Header("地面探测")]
|
||||
[Tooltip("通常复用 PlayerMovement 下的 GroundCheck 子对象")]
|
||||
[SerializeField] private Transform _groundProbe;
|
||||
[SerializeField] private LayerMask _groundLayer;
|
||||
[SerializeField] private float _probeRadius = 0.15f;
|
||||
|
||||
private AudioSource _audioSource;
|
||||
private readonly Collider2D[] _probeBuffer = new Collider2D[4];
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 优先使用同对象已有的 AudioSource,否则自动添加
|
||||
_audioSource = GetComponent<AudioSource>();
|
||||
if (_audioSource == null)
|
||||
_audioSource = gameObject.AddComponent<AudioSource>();
|
||||
|
||||
_audioSource.spatialBlend = 0f; // 始终 2D
|
||||
_audioSource.playOnAwake = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 由 PlayerFeedback.PlayFootstep() 调用。
|
||||
/// </summary>
|
||||
public void Play()
|
||||
{
|
||||
if (_config == null) return;
|
||||
|
||||
var material = DetectGroundMaterial();
|
||||
var entry = _config.GetEntry(material);
|
||||
if (entry == null) return;
|
||||
|
||||
var e = entry.Value;
|
||||
if (e.clips == null || e.clips.Length == 0) return;
|
||||
|
||||
var clip = e.clips[Random.Range(0, e.clips.Length)];
|
||||
if (clip == null) return;
|
||||
|
||||
// pitchVariance 为 [0.8, 1.2],以 1.0 为中心扩展偏移区间
|
||||
float half = e.pitchVariance - 1f;
|
||||
_audioSource.pitch = Random.Range(1f - half, 1f + half);
|
||||
_audioSource.PlayOneShot(clip, e.volume);
|
||||
}
|
||||
|
||||
// ── 地面材质探测 ──────────────────────────────────────────────────────
|
||||
|
||||
private FootstepMaterial DetectGroundMaterial()
|
||||
{
|
||||
Vector2 origin = _groundProbe != null
|
||||
? (Vector2)_groundProbe.position
|
||||
: (Vector2)transform.position + Vector2.down * 0.5f;
|
||||
|
||||
int count = Physics2D.OverlapCircleNonAlloc(origin, _probeRadius, _probeBuffer, _groundLayer);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var marker = _probeBuffer[i].GetComponent<FootstepMaterialMarker>();
|
||||
if (marker != null)
|
||||
return marker.material;
|
||||
}
|
||||
|
||||
return FootstepMaterial.Stone; // 默认回落
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
Gizmos.color = new Color(0.6f, 1f, 0.6f, 0.5f);
|
||||
Vector3 origin = _groundProbe != null
|
||||
? _groundProbe.position
|
||||
: transform.position + Vector3.down * 0.5f;
|
||||
Gizmos.DrawWireSphere(origin, _probeRadius);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Assets/_Game/Scripts/Audio/FootstepSoundPlayer.cs.meta
Normal file
11
Assets/_Game/Scripts/Audio/FootstepSoundPlayer.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a74182d14151114ea7691f3e7183583
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user