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(); } if (playerHealth == null) { playerHealth = playerObject.GetComponent(); } } 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); } } }