using UnityEngine; using UnityEngine.Events; public class SlidingDoor : MonoBehaviour { public enum SlideAxis { X, Y, Z } public enum SlideDirection { Positive = 1, Negative = -1 } [Header("Slide Settings")] [Tooltip("Local axis the door slides along.")] [SerializeField] private SlideAxis axis = SlideAxis.X; [Tooltip("Which way along the axis the door opens.")] [SerializeField] private SlideDirection direction = SlideDirection.Positive; [Tooltip("How far the door travels when fully open.")] [SerializeField] private float slideDistance = 2f; [Tooltip("Movement speed (units per second).")] [SerializeField] private float speed = 3f; [Header("Start State")] [SerializeField] private bool startOpen = false; [Header("Events")] public UnityEvent OnOpened; public UnityEvent OnClosed; private Vector3 m_closedPos; private Vector3 m_openPos; private Vector3 m_targetPos; private bool m_isOpen; private bool m_eventFiredOpen; private bool m_eventFiredClosed; private void Awake() { m_closedPos = transform.localPosition; m_openPos = m_closedPos + GetSlideVector() * slideDistance; if (startOpen) { transform.localPosition = m_openPos; m_isOpen = true; } m_targetPos = m_isOpen ? m_openPos : m_closedPos; } private void Update() { transform.localPosition = Vector3.MoveTowards( transform.localPosition, m_targetPos, speed * Time.deltaTime); if (Vector3.Distance(transform.localPosition, m_openPos) < 0.01f && !m_eventFiredOpen) { m_eventFiredOpen = true; m_eventFiredClosed = false; OnOpened?.Invoke(); } else if (Vector3.Distance(transform.localPosition, m_closedPos) < 0.01f && !m_eventFiredClosed) { m_eventFiredClosed = true; m_eventFiredOpen = false; OnClosed?.Invoke(); } } public void Open() { m_isOpen = true; m_targetPos = m_openPos; } public void Close() { m_isOpen = false; m_targetPos = m_closedPos; } public void Toggle() { if (m_isOpen) Close(); else Open(); } private Vector3 GetSlideVector() { float sign = (float)direction; return axis switch { SlideAxis.X => new Vector3(sign, 0f, 0f), SlideAxis.Y => new Vector3(0f, sign, 0f), SlideAxis.Z => new Vector3(0f, 0f, sign), _ => Vector3.right, }; } #if UNITY_EDITOR private void OnDrawGizmos() { Vector3 worldClosed = transform.parent != null ? transform.parent.TransformPoint(transform.localPosition) : transform.position; Vector3 slideVec = transform.TransformDirection(GetSlideVector()) * slideDistance; Gizmos.color = Color.cyan; Gizmos.DrawLine(worldClosed, worldClosed + slideVec); Gizmos.DrawWireSphere(worldClosed + slideVec, 0.08f); } #endif }