Files
2026-07-08 20:42:51 +08:00

159 lines
5.3 KiB
C#

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);
}
}
}
}