Mission6Manager.
cs Script
// File: Scripts/Missions/Mission6Manager.cs
using UnityEngine;
using TMPro;
using UnityEngine.SceneManagement;
using System.Collections;
public class Mission6Manager : MonoBehaviour
{
[Header("Player")]
public Transform playerCam;
public CharacterController playerController;
[Header("Points")]
public Transform point1, doctorPoint1, doctorPoint2;
[Header("Scene References")]
public GameObject scientist;
public Animator doorAnimator;
public ParticleSystem smokeEffect;
public GameObject[] flashlightRobots;
[Header("UI & Audio")]
public AudioSource audioSource;
public AudioClip bgMusic;
public AudioClip ciroLine1, ciroLine2;
public AudioClip scientistLine1, scientistLine2, scientistLine3;
public AudioClip alarmClip, doorOpenClip;
public TextMeshProUGUI subtitleText;
public CanvasGroup subtitleCanvas;
public float subtitleFadeSpeed = 4f;
[Header("Effects")]
public GameObject screenDarkOverlay;
public Light alarmLight;
public float alarmFlashSpeed = 1.5f;
private bool triggeredPoint1 = false;
private bool alarmActive = false;
void Start()
{
playerController.enabled = false;
subtitleCanvas.alpha = 0f;
if (screenDarkOverlay != null) screenDarkOverlay.SetActive(false);
StartCoroutine(StartIntro());
}
void Update()
{
if (!triggeredPoint1 && Vector3.Distance(playerCam.position, point1.position) <
2f)
{
triggeredPoint1 = true;
StartCoroutine(TriggerPoint1Events());
}
if (alarmActive && alarmLight != null)
{
float intensity = Mathf.PingPong(Time.time * alarmFlashSpeed, 1f);
alarmLight.intensity = intensity * 2f;
}
}
IEnumerator StartIntro()
{
PlayMusic(bgMusic);
yield return new WaitForSeconds(1f);
yield return Speak("Ciro", "System initializing. You're cleared for movement.",
ciroLine1);
yield return Speak("Ciro", "Proceed to the checkpoint, and keep your guard up.",
ciroLine2);
playerController.enabled = true;
}
IEnumerator TriggerPoint1Events()
{
yield return Speak("Scientist", "Ah, you made it. I was beginning to worry.",
scientistLine1);
yield return Speak("Ciro", "Something feels... off. Stay alert.", ciroLine2);
yield return Speak("Scientist", "Don't be so dramatic, I just have news.",
scientistLine2);
MoveTo(doctorPoint1, scientist);
yield return new WaitForSeconds(4f);
yield return Speak("Scientist", "System breach... No! It's too soon!",
scientistLine3);
TriggerAlarmSequence();
MoveTo(doctorPoint2, scientist);
yield return new WaitUntil(() => Vector3.Distance(scientist.transform.position,
doctorPoint2.position) < 1.5f);
OpenDoorWithSmoke();
}
void PlayMusic(AudioClip clip)
{
if (audioSource != null)
{
audioSource.clip = clip;
audioSource.loop = true;
audioSource.Play();
}
}
void TriggerAlarmSequence()
{
alarmActive = true;
if (screenDarkOverlay != null) screenDarkOverlay.SetActive(true);
if (audioSource != null) audioSource.PlayOneShot(alarmClip);
foreach (var bot in flashlightRobots)
{
bot.SetActive(true);
}
}
void OpenDoorWithSmoke()
{
if (doorAnimator != null) doorAnimator.SetTrigger("Open");
if (smokeEffect != null) smokeEffect.Play();
if (audioSource != null) audioSource.PlayOneShot(doorOpenClip);
}
void MoveTo(Transform dest, GameObject obj)
{
if (obj.TryGetComponent(out Animator anim)) anim.SetTrigger("Walk");
var follower = obj.GetComponent<NPCFollower>() ??
obj.AddComponent<NPCFollower>();
follower.Init(dest);
}
IEnumerator Speak(string speaker, string line, AudioClip clip)
{
if (clip != null && audioSource != null) audioSource.PlayOneShot(clip);
subtitleText.text = $"[{speaker}]: {line}";
subtitleCanvas.alpha = 1f;
yield return new WaitForSeconds(clip != null ? clip.length : 2f);
subtitleCanvas.alpha = 0f;
subtitleText.text = "";
}
}