Files
PIM_Laba5/Assets/Scripts/NoiseManager.cs
T
2026-05-26 01:16:57 +03:00

106 lines
2.7 KiB
C#

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);
}
}
}
}