Files
HeadlessHazard/Assets/Code/Scripts/Interaction/SlidingDoor.cs
2026-03-30 18:01:33 +02:00

115 lines
3.1 KiB
C#

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
}