157 lines
5.0 KiB
C#
157 lines
5.0 KiB
C#
using System.Collections;
|
||
using UnityEngine;
|
||
|
||
/// <summary>
|
||
/// Контроллер арены босса на 2-м уровне.
|
||
/// Блокирует двери отсека при входе игрока (карантинный локдаун) и не выпускает
|
||
/// до тех пор, пока босс не будет побежден или пока игрок не погибнет.
|
||
/// </summary>
|
||
public class BossArenaController : MonoBehaviour
|
||
{
|
||
[Header("Ссылки на объекты арены")]
|
||
public TitanBossAI bossAI;
|
||
public GameObject blastDoorRoot;
|
||
public Collider blastDoorCollider;
|
||
public Light emergencyLight;
|
||
|
||
[Header("Состояние арены")]
|
||
public bool isLockdownActive = false;
|
||
public bool isBossDefeated = false;
|
||
|
||
public bool AreDoorsLocked => isLockdownActive;
|
||
|
||
public void LockArenaDoors()
|
||
{
|
||
isLockdownActive = true;
|
||
}
|
||
|
||
public void BindBossForTest(MutantHealth health)
|
||
{
|
||
if (health != null)
|
||
{
|
||
health.OnDied += OnBossDefeated;
|
||
}
|
||
}
|
||
|
||
private Vector3 doorOpenPos;
|
||
private Vector3 doorClosedPos;
|
||
private Coroutine doorMoveCoroutine;
|
||
|
||
private void Awake()
|
||
{
|
||
if (blastDoorRoot != null)
|
||
{
|
||
doorClosedPos = blastDoorRoot.transform.position;
|
||
doorOpenPos = doorClosedPos + Vector3.up * 4.2f;
|
||
// Изначально ворота открыты, чтобы игрок мог войти
|
||
blastDoorRoot.transform.position = doorOpenPos;
|
||
if (blastDoorCollider != null) blastDoorCollider.enabled = false;
|
||
}
|
||
|
||
if (emergencyLight != null)
|
||
{
|
||
emergencyLight.color = new Color(0.2f, 0.8f, 0.4f); // Зеленый дежурный свет до боя
|
||
emergencyLight.intensity = 1.5f;
|
||
}
|
||
}
|
||
|
||
private void OnTriggerEnter(Collider other)
|
||
{
|
||
if (isLockdownActive || isBossDefeated) return;
|
||
|
||
if (other.CompareTag("Player") || other.GetComponentInParent<PlayerMovement>() != null)
|
||
{
|
||
InitiateLockdown();
|
||
}
|
||
}
|
||
|
||
public void InitiateLockdown()
|
||
{
|
||
if (isLockdownActive || isBossDefeated) return;
|
||
isLockdownActive = true;
|
||
|
||
Debug.Log("<color=red>[Арена Босса] КАРАНТИННАЯ БЛОКИРОВКА: ВХОД ЗАПЕРТ!</color>");
|
||
|
||
// Звук тревоги и герметизации
|
||
GameAudioSynthesizer.PlayLockdownAlarm();
|
||
|
||
// Закрываем гермоворота
|
||
if (blastDoorRoot != null)
|
||
{
|
||
if (doorMoveCoroutine != null) StopCoroutine(doorMoveCoroutine);
|
||
doorMoveCoroutine = StartCoroutine(RoutineMoveDoor(doorClosedPos, true));
|
||
}
|
||
|
||
// Включаем пульсирующий аварийный красный свет
|
||
if (emergencyLight != null)
|
||
{
|
||
emergencyLight.color = new Color(1.0f, 0.15f, 0.15f);
|
||
emergencyLight.intensity = 2.8f;
|
||
}
|
||
|
||
// Будим босса
|
||
if (bossAI != null)
|
||
{
|
||
bossAI.WakeUp();
|
||
}
|
||
}
|
||
|
||
public void OnBossDefeated()
|
||
{
|
||
if (isBossDefeated) return;
|
||
isBossDefeated = true;
|
||
isLockdownActive = false;
|
||
|
||
Debug.Log("<color=green>[Арена Босса] БОСС УНИЧТОЖЕН: ВОРОТА РАЗБЛОКИРОВАНЫ!</color>");
|
||
|
||
// Звук разблокировки гидравлики
|
||
if (Application.isPlaying)
|
||
GameAudioSynthesizer.PlayDoorHydraulic();
|
||
|
||
// Открываем ворота
|
||
if (blastDoorRoot != null && Application.isPlaying)
|
||
{
|
||
if (doorMoveCoroutine != null) StopCoroutine(doorMoveCoroutine);
|
||
doorMoveCoroutine = StartCoroutine(RoutineMoveDoor(doorOpenPos, false));
|
||
}
|
||
else if (blastDoorRoot != null)
|
||
{
|
||
blastDoorRoot.transform.position = doorOpenPos;
|
||
}
|
||
|
||
// Возвращаем свет в спокойный зеленый/бирюзовый
|
||
if (emergencyLight != null)
|
||
{
|
||
emergencyLight.color = new Color(0.2f, 1.0f, 0.5f);
|
||
emergencyLight.intensity = 2.0f;
|
||
}
|
||
}
|
||
|
||
private IEnumerator RoutineMoveDoor(Vector3 targetPos, bool enableColliderAtEnd)
|
||
{
|
||
if (blastDoorCollider != null)
|
||
{
|
||
if (enableColliderAtEnd) blastDoorCollider.enabled = true;
|
||
else blastDoorCollider.enabled = false;
|
||
}
|
||
|
||
float duration = 1.0f;
|
||
float elapsed = 0f;
|
||
Vector3 start = blastDoorRoot.transform.position;
|
||
|
||
while (elapsed < duration)
|
||
{
|
||
elapsed += Time.deltaTime;
|
||
float t = Mathf.SmoothStep(0f, 1f, elapsed / duration);
|
||
blastDoorRoot.transform.position = Vector3.Lerp(start, targetPos, t);
|
||
yield return null;
|
||
}
|
||
|
||
blastDoorRoot.transform.position = targetPos;
|
||
if (enableColliderAtEnd && blastDoorCollider != null)
|
||
{
|
||
blastDoorCollider.enabled = true;
|
||
}
|
||
}
|
||
}
|