using System.Collections; using UnityEngine; #if DOTWEEN using DG.Tweening; #endif namespace EndingSystem { public class EndingDoorController : MonoBehaviour { [Header("Door References")] public Transform leftDoor; public Transform rightDoor; [Header("Animation Settings")] [Tooltip("The initial small angle to open the door (e.g., crack it open slightly)")] public float openLittleAngle = 10f; public float openLittleDuration = 1.5f; [Tooltip("How long to pause before fully opening the door")] public float pauseDuration = 0.5f; [Tooltip("The final angle to fully open the door")] public float fullOpenAngle = 90f; public float fullOpenDuration = 3f; [Tooltip("The axis of rotation for the doors (usually Vector3.up)")] public Vector3 rotationAxis = Vector3.up; [Tooltip("If true, the right door rotates in the opposite direction of the left door")] public bool mirrorRightDoor = true; #if DOTWEEN [Header("DOTween")] public Ease openLittleEase = Ease.InOutSine; public Ease fullOpenEase = Ease.InOutSine; #endif private Quaternion leftClosedRotation; private Quaternion rightClosedRotation; #if DOTWEEN private Sequence currentSequence; #endif public void OpenDoor(bool useUnscaledTime = false) { #if DOTWEEN PlayOpenDoor(useUnscaledTime); #else StartCoroutine(DoorAnimationCoroutine()); #endif } #if DOTWEEN private void OnDisable() { if (currentSequence != null) { currentSequence.Kill(false); currentSequence = null; } } private void CacheClosedRotations() { if (leftDoor != null) leftClosedRotation = leftDoor.localRotation; if (rightDoor != null) rightClosedRotation = rightDoor.localRotation; } private void PlayOpenDoor(bool useUnscaledTime) { CacheClosedRotations(); if (leftDoor != null) leftDoor.DOKill(); if (rightDoor != null) rightDoor.DOKill(); if (currentSequence != null) { currentSequence.Kill(false); currentSequence = null; } currentSequence = DOTween.Sequence(); currentSequence.SetUpdate(useUnscaledTime); currentSequence.Append(CreateRotateTween(openLittleAngle, Mathf.Max(0.0001f, openLittleDuration), openLittleEase, useUnscaledTime)); if (pauseDuration > 0f) currentSequence.AppendInterval(pauseDuration); currentSequence.Append(CreateRotateTween(fullOpenAngle, Mathf.Max(0.0001f, fullOpenDuration), fullOpenEase, useUnscaledTime)); } private Tween CreateRotateTween(float angle, float duration, Ease ease, bool useUnscaledTime) { Sequence seq = DOTween.Sequence(); seq.SetUpdate(useUnscaledTime); Vector3 axis = rotationAxis.sqrMagnitude > 0f ? rotationAxis.normalized : Vector3.up; if (leftDoor != null) { Quaternion target = leftClosedRotation * Quaternion.AngleAxis(angle, axis); Tween t = leftDoor.DOLocalRotateQuaternion(target, duration).SetEase(ease).SetUpdate(useUnscaledTime); seq.Join(t); } if (rightDoor != null) { float rightAngle = mirrorRightDoor ? -angle : angle; Quaternion target = rightClosedRotation * Quaternion.AngleAxis(rightAngle, axis); Tween t = rightDoor.DOLocalRotateQuaternion(target, duration).SetEase(ease).SetUpdate(useUnscaledTime); seq.Join(t); } return seq; } #endif private IEnumerator DoorAnimationCoroutine() { yield return StartCoroutine(RotateDoors(0f, openLittleAngle, openLittleDuration)); yield return new WaitForSeconds(pauseDuration); yield return StartCoroutine(RotateDoors(openLittleAngle, fullOpenAngle, fullOpenDuration)); } private IEnumerator RotateDoors(float startAngle, float endAngle, float duration) { float t = 0f; while (t < 1f) { t += Time.deltaTime / duration; float currentAngle = Mathf.Lerp(startAngle, endAngle, t); if (leftDoor != null) { leftDoor.localRotation = Quaternion.AngleAxis(currentAngle, rotationAxis); } if (rightDoor != null) { float rightAngle = mirrorRightDoor ? -currentAngle : currentAngle; rightDoor.localRotation = Quaternion.AngleAxis(rightAngle, rotationAxis); } yield return null; } if (leftDoor != null) leftDoor.localRotation = Quaternion.AngleAxis(endAngle, rotationAxis); if (rightDoor != null) { float rightAngleFinal = mirrorRightDoor ? -endAngle : endAngle; rightDoor.localRotation = Quaternion.AngleAxis(rightAngleFinal, rotationAxis); } } } }