first commit
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class NoiseManager : MonoBehaviour
|
||||
{
|
||||
[System.Serializable]
|
||||
public class NoiseEvent
|
||||
{
|
||||
public Vector3 position;
|
||||
public float intensity;
|
||||
public float timestamp;
|
||||
}
|
||||
|
||||
public float noiseLifetime = 1.25f;
|
||||
|
||||
public static NoiseManager Instance { get; private set; }
|
||||
public static IReadOnlyList<NoiseEvent> ActiveNoises => activeNoises;
|
||||
|
||||
private static readonly List<NoiseEvent> activeNoises = new List<NoiseEvent>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
PruneExpiredNoise();
|
||||
}
|
||||
|
||||
public static void EmitNoise(Vector3 position, float intensity)
|
||||
{
|
||||
EnsureInstance();
|
||||
PruneExpiredNoise();
|
||||
|
||||
// Шум живёт короткое время, чтобы враги реагировали на свежие события, а не на старые следы.
|
||||
activeNoises.Add(new NoiseEvent
|
||||
{
|
||||
position = position,
|
||||
intensity = intensity,
|
||||
timestamp = Time.time
|
||||
});
|
||||
}
|
||||
|
||||
public static NoiseEvent GetClosestNoise(Vector3 listenerPosition, float hearingRange)
|
||||
{
|
||||
PruneExpiredNoise();
|
||||
|
||||
NoiseEvent closest = null;
|
||||
float closestDistance = float.MaxValue;
|
||||
|
||||
for (int i = 0; i < activeNoises.Count; i++)
|
||||
{
|
||||
NoiseEvent noise = activeNoises[i];
|
||||
float effectiveRange = Mathf.Max(0.1f, hearingRange * noise.intensity);
|
||||
float distance = Vector3.Distance(listenerPosition, noise.position);
|
||||
|
||||
if (distance > effectiveRange || distance >= closestDistance)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
closest = noise;
|
||||
closestDistance = distance;
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
public static void ClearNoise()
|
||||
{
|
||||
activeNoises.Clear();
|
||||
}
|
||||
|
||||
private static void EnsureInstance()
|
||||
{
|
||||
if (Instance != null || !Application.isPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject managerObject = new GameObject("NoiseManager");
|
||||
Instance = managerObject.AddComponent<NoiseManager>();
|
||||
}
|
||||
|
||||
private static void PruneExpiredNoise()
|
||||
{
|
||||
float lifetime = Instance != null ? Instance.noiseLifetime : 1.25f;
|
||||
float minTimestamp = Time.time - lifetime;
|
||||
|
||||
for (int i = activeNoises.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (activeNoises[i].timestamp < minTimestamp)
|
||||
{
|
||||
activeNoises.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user