115 lines
3.1 KiB
C#
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
|
|
}
|