摄像机区域的优化

This commit is contained in:
2026-05-17 07:56:12 +08:00
parent f264329751
commit d25f237e76
62 changed files with 25774 additions and 5450 deletions

View 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
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a74182d14151114ea7691f3e7183583
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: