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

240 lines
6.2 KiB
C#

using System.Text;
using UnityEngine;
using UnityEngine.UI;
public class StealthIndicator : MonoBehaviour
{
[Header("UI")]
public Image stateBar;
public Text statusText;
public Text controlsText;
public Text debugText;
public Text healthText;
public Text gameOverText;
[Header("References")]
public PlayerStealth playerStealth;
public PlayerHealth playerHealth;
private readonly StringBuilder debugBuilder = new StringBuilder(256);
private bool subscribedToPlayerHealth;
private void Start()
{
PopulateControlsText();
FindPlayerReferences();
SubscribeToPlayerHealth();
if (gameOverText != null)
{
gameOverText.gameObject.SetActive(false);
}
}
private void Update()
{
FindPlayerReferences();
SubscribeToPlayerHealth();
UpdateThreatState();
UpdateDebugText();
UpdateHealthText();
}
private void PopulateControlsText()
{
if (controlsText == null)
{
return;
}
controlsText.text =
"WASD - движение\n" +
"Mouse - обзор\n" +
"Shift - бег / больше шума\n" +
"Ctrl - присесть / меньше шума\n" +
"R - тестовый шум";
}
private void UpdateThreatState()
{
int suspicionCount = 0;
int alertCount = 0;
foreach (EnemyStateMachine enemy in EnemyStateMachine.ActiveEnemies)
{
if (enemy == null)
{
continue;
}
if (enemy.CurrentState == EnemyStateMachine.State.Alert)
{
alertCount++;
}
else if (enemy.CurrentState == EnemyStateMachine.State.Suspicion)
{
suspicionCount++;
}
}
Color stateColor = new Color(0.18f, 0.85f, 0.34f, 0.95f);
string stateLabel = "Скрытность: безопасно";
if (playerHealth != null && playerHealth.HasCompletedLevel)
{
stateColor = new Color(0.3f, 1f, 0.42f, 0.95f);
stateLabel = "Скрытность: выход достигнут";
}
else if (playerHealth != null && !playerHealth.IsAlive)
{
stateColor = new Color(0.95f, 0.15f, 0.15f, 0.95f);
stateLabel = "Скрытность: провал";
}
else if (alertCount > 0)
{
stateColor = new Color(0.95f, 0.25f, 0.2f, 0.95f);
stateLabel = "Скрытность: обнаружен";
}
else if (suspicionCount > 0)
{
stateColor = new Color(1f, 0.8f, 0.15f, 0.95f);
stateLabel = "Скрытность: подозрение";
}
if (stateBar != null)
{
stateBar.color = stateColor;
}
if (statusText != null)
{
statusText.text = stateLabel;
statusText.color = stateColor;
}
}
private void UpdateDebugText()
{
if (debugText == null)
{
return;
}
int suspicionCount = 0;
int alertCount = 0;
foreach (EnemyStateMachine enemy in EnemyStateMachine.ActiveEnemies)
{
if (enemy == null)
{
continue;
}
if (enemy.CurrentState == EnemyStateMachine.State.Suspicion)
{
suspicionCount++;
}
if (enemy.CurrentState == EnemyStateMachine.State.Alert)
{
alertCount++;
}
}
debugBuilder.Length = 0;
if (playerStealth != null)
{
debugBuilder.Append("Поза: ");
debugBuilder.Append(playerStealth.IsCrouching ? "присел" : "стоит");
debugBuilder.Append('\n');
debugBuilder.Append("Шум: ");
debugBuilder.Append(playerStealth.CurrentNoiseLabel);
debugBuilder.Append('\n');
}
else
{
debugBuilder.Append("Поза: нет данных\n");
debugBuilder.Append("Шум: нет данных\n");
}
debugBuilder.Append("Враги в Suspicion: ");
debugBuilder.Append(suspicionCount);
debugBuilder.Append('\n');
debugBuilder.Append("Враги в Alert: ");
debugBuilder.Append(alertCount);
debugText.text = debugBuilder.ToString();
}
private void UpdateHealthText()
{
if (healthText == null || playerHealth == null)
{
return;
}
healthText.text = "Здоровье: " + playerHealth.health;
healthText.color = playerHealth.IsAlive ? Color.white : Color.red;
}
private void FindPlayerReferences()
{
if (playerStealth != null && playerHealth != null)
{
return;
}
GameObject playerObject = GameObject.FindGameObjectWithTag("Player");
if (playerObject == null)
{
return;
}
if (playerStealth == null)
{
playerStealth = playerObject.GetComponent<PlayerStealth>();
}
if (playerHealth == null)
{
playerHealth = playerObject.GetComponent<PlayerHealth>();
}
}
private void SubscribeToPlayerHealth()
{
if (playerHealth == null)
{
return;
}
if (subscribedToPlayerHealth)
{
return;
}
playerHealth.Died += HandlePlayerDeath;
playerHealth.LevelCompleted += HandleLevelCompleted;
subscribedToPlayerHealth = true;
}
private void HandlePlayerDeath()
{
if (gameOverText != null)
{
gameOverText.gameObject.SetActive(true);
gameOverText.text = "Игрок устранен";
gameOverText.color = new Color(1f, 0.2f, 0.2f, 1f);
}
}
private void HandleLevelCompleted()
{
if (gameOverText != null)
{
gameOverText.gameObject.SetActive(true);
gameOverText.text = "Миссия выполнена";
gameOverText.color = new Color(0.35f, 1f, 0.45f, 1f);
}
}
}