Kursach_StealthAction/Assets/Scripts/EchoTrigger.cs

140 lines
4.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using UnityEngine.InputSystem;
public class EchoTrigger : MonoBehaviour
{
[Header("Связь с шейдером")]
public Material echoMaterial;
[Header("Настройки шагов")]
public float stepDistance = 1.5f;
public float waveSpeed = 15f;
[Header("Радиусы звука (Шум)")]
public float sneakRadius = 5f;
public float walkRadius = 15f;
public float runRadius = 30f;
[Header("Яркость волны (Интенсивность)")]
public float sneakIntensity = 0.3f; // Тусклый свет для стелса
public float walkIntensity = 1.0f; // Обычный свет для шага
public float runIntensity = 3.0f; // Очень яркая вспышка для бега
// Пул из 3 одновременных волн
private const int MAX_WAVES = 3;
private float[] waveRadii = new float[MAX_WAVES];
private float[] waveMaxRadii = new float[MAX_WAVES];
private float[] waveIntensities = new float[MAX_WAVES]; // Память для яркости каждой волны
private bool[] waveActive = new bool[MAX_WAVES];
private Vector3 lastPosition;
private float distanceMoved = 0f;
void Start()
{
if (echoMaterial != null)
{
for (int i = 0; i < MAX_WAVES; i++)
{
echoMaterial.SetFloat("_EchoRadius" + (i + 1), 0f);
echoMaterial.SetFloat("_EchoOpacity" + (i + 1), 0f);
}
}
lastPosition = transform.position;
}
void Update()
{
if (echoMaterial == null) return;
Vector3 currentPos = new Vector3(transform.position.x, 0, transform.position.z);
Vector3 lastPos = new Vector3(lastPosition.x, 0, lastPosition.z);
distanceMoved += Vector3.Distance(currentPos, lastPos);
lastPosition = transform.position;
if (distanceMoved >= stepDistance)
{
distanceMoved = 0f;
TriggerStepWave();
}
for (int i = 0; i < MAX_WAVES; i++)
{
if (waveActive[i])
{
waveRadii[i] += waveSpeed * Time.deltaTime;
echoMaterial.SetFloat("_EchoRadius" + (i + 1), waveRadii[i]);
// ВЫЧИСЛЯЕМ ПРОЗРАЧНОСТЬ с учетом стартовой яркости
// Умножаем на waveIntensities[i], чтобы бег был ярче, а стелс тусклее
float opacity = (1f - (waveRadii[i] / waveMaxRadii[i])) * waveIntensities[i];
// Mathf.Max не дает уйти в минус, но РАЗРЕШАЕТ быть больше 1 (для HDR свечения)
opacity = Mathf.Max(0f, opacity);
echoMaterial.SetFloat("_EchoOpacity" + (i + 1), opacity);
if (waveRadii[i] > waveMaxRadii[i])
{
waveActive[i] = false;
echoMaterial.SetFloat("_EchoRadius" + (i + 1), 0f);
echoMaterial.SetFloat("_EchoOpacity" + (i + 1), 0f);
}
}
}
}
void TriggerStepWave()
{
var keyboard = Keyboard.current;
if (keyboard == null) return;
float targetMax = walkRadius;
float targetIntensity = walkIntensity;
if (keyboard.leftShiftKey.isPressed)
{
targetMax = runRadius;
targetIntensity = runIntensity;
}
else if (keyboard.leftCtrlKey.isPressed)
{
targetMax = sneakRadius;
targetIntensity = sneakIntensity;
}
// Ищем свободный слот
int waveIndex = -1;
for (int i = 0; i < MAX_WAVES; i++)
{
if (!waveActive[i])
{
waveIndex = i;
break;
}
}
// Если занято, берем самую старую волну
if (waveIndex == -1)
{
float maxRad = -1f;
for (int i = 0; i < MAX_WAVES; i++)
{
if (waveRadii[i] > maxRad)
{
maxRad = waveRadii[i];
waveIndex = i;
}
}
}
// Назначаем волне её радиус и её личную яркость!
waveMaxRadii[waveIndex] = targetMax;
waveIntensities[waveIndex] = targetIntensity;
waveRadii[waveIndex] = 0f;
waveActive[waveIndex] = true;
echoMaterial.SetFloat("_EchoOpacity" + (waveIndex + 1), targetIntensity);
echoMaterial.SetVector("_EchoPosition" + (waveIndex + 1), transform.position);
}
}