using System.Collections; using System.Collections.Generic; using UnityEngine; using Sirenix.OdinInspector; using KairoEngine.Core; using KairoEngine.SFX; namespace KairoEngine.CharacterSystem { public enum DoorState { Open, Closed, Locked, LockedOpen, Blocked } public class DoorController : MonoBehaviour { public string title = "Door 001"; public DoorState doorState = DoorState.Closed; public GameObject doorObject; public DoorTrigger doorTrigger; public Transform doorOpenTransform; public Transform doorClosedTransform; public float animationTime; public SFXClip soundEffect; private ActionController actionController; private bool inMotion = false; private float time = 0f; public static Dictionary> list = new Dictionary>(); public static void StartListening(string title, System.Action listener) { System.Action action = null; if (list.TryGetValue(title, out action)) { action += listener; list[title] = action; } else { action += listener; list.Add(title, action); } } public static void StopListening(string title, System.Action listener) { System.Action action = null; if (list.TryGetValue(title, out action)) { action -= listener; list[title] = action; } } public static void Trigger(string title, DoorState state) { System.Action action = null; if (list.TryGetValue(title, out action)) { if(action != null) action(state); } } void OnEnable() { DoorController.StartListening(title, ChangeState); } void OnDisable() { DoorController.StopListening(title, ChangeState); } void Start() { actionController = GetComponent(); if(actionController == null) Debug.LogError("Missing ActionController", this.gameObject); } void Update() { time += Time.deltaTime; if(doorTrigger.charactersInRange.Count > 0 && inMotion == false) { if(doorState == DoorState.Closed) ChangeState(DoorState.Open); } else if(doorTrigger.charactersInRange.Count == 0 && inMotion == false) { if(doorState == DoorState.Open) ChangeState(DoorState.Closed); } } public void ChangeState(DoorState newState) { switch (newState) { case DoorState.Open: if(doorState == DoorState.Closed) { Open(); doorState = DoorState.Open; } else if(doorState == DoorState.LockedOpen) doorState = DoorState.Open; break; case DoorState.Closed: if(doorState == DoorState.Open || doorState == DoorState.LockedOpen) { Close(); doorState = DoorState.Closed; } else if(doorState == DoorState.Locked) doorState = DoorState.Closed; break; case DoorState.Locked: if(doorState == DoorState.Closed) doorState = DoorState.Locked; else if(doorState == DoorState.Open) { Close(); doorState = DoorState.Locked; } else if(doorState == DoorState.LockedOpen) { Close(); doorState = DoorState.Locked; } break; case DoorState.LockedOpen: if(doorState == DoorState.Open) doorState = DoorState.LockedOpen; else if(doorState == DoorState.Closed || doorState == DoorState.Locked) { Open(); doorState = DoorState.LockedOpen; } break; case DoorState.Blocked: doorState = DoorState.Blocked; break; default: break; } } public void Open() { if(doorState == DoorState.Open) return; StartCoroutine(Animate(doorClosedTransform.position, doorOpenTransform.position)); if(soundEffect != null) SoundController.EmmitSound(soundEffect, doorClosedTransform.position); } public void Close() { if(doorState == DoorState.Closed) return; StartCoroutine(Animate(doorOpenTransform.position, doorClosedTransform.position)); if(soundEffect != null) SoundController.EmmitSound(soundEffect, doorOpenTransform.position); } IEnumerator Animate(Vector3 start, Vector3 end) { inMotion = true; time = 0f; while(animationTime > time) { float x = Mathf.Lerp(start.x, end.x, time/animationTime); float y = Mathf.Lerp(start.y, end.y, time/animationTime); float z = Mathf.Lerp(start.z, end.z, time/animationTime); doorObject.transform.position = new Vector3(x, y, z); yield return null; } yield return null; inMotion = false; } } }