using UnityEngine; public abstract class State : MonoBehaviour { public abstract State RunCurrentState(); }
public class StateManager : MonoBehaviour { public State currentState; void Update() { RunStateMachine(); } private void RunStateMachine() { State nextState = currentState?.RunCurrentState(); if (nextState != null) { SwitchToTheNextState(nextState); } } private void SwitchToTheNextState(State nextState) { currentState = nextState; } }
using UnityEngine; using UnityEngine.AI; public class IdleState : State { public bool playerInSight; public ChaseState chaseState; public Transform[] waypoints; public NavMeshAgent agent; public AI_FOV fov; public Cube_Hide cubeHide; public SoundcollisionTEST soundcollisionTEST; public Animator animator; public BasketForLab basketForLab; public BasketForNatural basketForNatural; public Potions potions; private int currentWaypointIndex = 0; private float idleTimer = 0f; private AudioSource scarySound; public GameObject dynamicMusic; public GameObject voiceLines; private void Start() { InitializeAgentDestination(); scarySound = GetComponent(); scarySound.Play(); dynamicMusic.SetActive(true); voiceLines.SetActive(true); } private void Update() { HandlePatrol(); HandleSoundResponse(); HandleTaskInterruption(); playerInSight = fov.canSeePlayer; } private void InitializeAgentDestination() { if (waypoints.Length > 0) { agent.SetDestination(waypoints[currentWaypointIndex].position); } } private void HandlePatrol() { if (!agent.pathPending && agent.remainingDistance <= agent.stoppingDistance) { idleTimer += Time.deltaTime; animator.SetBool("isIdle", true); animator.SetBool("isWalking", false); if (idleTimer >= 3) { SetNextWaypoint(); animator.SetBool("isIdle", false); animator.SetBool("isWalking", true); idleTimer = 0; } } } private void HandleSoundResponse() { if (soundcollisionTEST.isSoundPlaying) { agent.SetDestination(soundcollisionTEST.soundPos.position); animator.SetBool("isIdle", false); animator.SetBool("isWalking", true); if (agent.remainingDistance <= agent.stoppingDistance) { ResetSoundResponse(); } } } private void ResetSoundResponse() { soundcollisionTEST.isSoundPlaying = false; idleTimer += Time.deltaTime; animator.SetBool("isIdle", true); if (idleTimer >= 3) { SetNextWaypoint(); idleTimer = 0; } } private void HandleTaskInterruption() { if (basketForNatural.taskMessedUp || basketForLab.taskMessedUp) { agent.SetDestination(basketForNatural.transform.position); if (agent.remainingDistance <= agent.stoppingDistance) { ResetTaskInterruption(); } } if (potions.taskMessedUp) { agent.SetDestination(potions.transform.position); if (agent.remainingDistance <= agent.stoppingDistance) { ResetTaskInterruption(); } } } private void ResetTaskInterruption() { idleTimer += Time.deltaTime; animator.SetBool("isIdle", true); if (idleTimer >= 3) { SetNextWaypoint(); animator.SetBool("isIdle", false); idleTimer = 0; } basketForNatural.taskMessedUp = false; basketForLab.taskMessedUp = false; } private void SetNextWaypoint() { animator.SetBool("isWalking", true); int waypointIndex = Random.Range(0, waypoints.Length); agent.SetDestination(waypoints[waypointIndex].position); } public override State RunCurrentState() { return playerInSight ? chaseState : this; } }
using UnityEngine; using UnityEngine.AI; public class ChaseState : State { public IdleState idleState; public AttackState attackState; public bool isInAttackRange; public NavMeshAgent agent; public AI_FOV fov; public GameObject player; public Animator animator; private void Update() { if (fov.canSeePlayer) { agent.SetDestination(player.transform.position); agent.speed = 2f; animator.SetBool("isIdle", false); animator.SetBool("isWalking", true); } } public override State RunCurrentState() { if (isInAttackRange) return attackState; if (!fov.canSeePlayer) { agent.speed = 1.27f; return idleState; } return this; } private void OnTriggerEnter(Collider other) { if (other.gameObject == player) { isInAttackRange = true; } } }
using System.Collections; using UnityEngine; using UnityEngine.AI; using UnityEngine.SceneManagement; using UnityEngine.UI; public class AttackState : State { public Animator anim; public CharacterController playerController; public GameObject mainCam; public Transform deathCameraPos; public Image fadingImage; public GameObject playerRig; public NavMeshAgent enemy; private void Start() { Color tempColor = fadingImage.color; tempColor.a = 0; fadingImage.color = tempColor; fadingImage.gameObject.SetActive(false); } public override State RunCurrentState() { TriggerDeathSequence(); return this; } void TriggerDeathSequence() { enemy.speed = 0; DisablePlayerController(); MoveCameraToPosition(); AnimationTrigger(); StartCoroutine(FadeToBlack()); StartCoroutine(EndGameAfterDelay(3)); } void DisablePlayerController() { playerController.enabled = false; } void AnimationTrigger() { anim.SetTrigger("deathAnimation"); } void MoveCameraToPosition() { mainCam.transform.position = deathCameraPos.position; } IEnumerator FadeToBlack() { fadingImage.gameObject.SetActive(true); float fadeDuration = 2f; Color fadeColor = fadingImage.color; for (float t = 0; t < fadeDuration; t += Time.deltaTime) { float alpha = Mathf.Lerp(0, 1, t / fadeDuration); fadeColor.a = alpha; fadingImage.color = fadeColor; yield return null; } fadeColor.a = 1f; fadingImage.color = fadeColor; } IEnumerator EndGameAfterDelay(float delay) { yield return new WaitForSeconds(delay); SceneManager.LoadScene("ClubPenguin"); } }