Files
Echo/Assets/_Project/Scripts/EndingSystem/FaintEndingSequenceController.cs
T
2026-07-08 20:42:51 +08:00

212 lines
7.6 KiB
C#

using UnityEngine;
using Core.InputLock;
#if DOTWEEN
using DG.Tweening;
#endif
namespace EndingSystem
{
public class FaintEndingSequenceController : MonoBehaviour
{
[Header("References")]
public Player.PlayerController playerController;
public Transform cameraPivot;
public Transform cameraTransform;
public CanvasGroup blackScreenCanvasGroup;
public GameObject endingUIPanel;
[Header("Input")]
public bool keepCursorLockedUntilEnd = true;
public bool switchToUIActionMapAtEnd = true;
#if DOTWEEN
[Header("DOTween")]
public bool useUnscaledTime = false;
public Ease step1Ease = Ease.InOutSine;
public Ease step3Ease = Ease.InOutSine;
public Ease step4Ease = Ease.InOutSine;
public Ease alphaEase = Ease.InOutSine;
#endif
[Header("Step 1")]
public float step1Duration = 1.2f;
public Vector3 step1CameraLocalOffset = new Vector3(0f, -0.4f, 0.3f);
public float step1Pitch = 35f;
[Range(0f, 1f)] public float step1Alpha = 0.65f;
[Header("Step 2")]
public float step2HoldDuration = 0.4f;
[Header("Step 3")]
public float step3Duration = 0.4f;
public Vector3 step3CameraLocalOffset = new Vector3(0f, -0.32f, 0.24f);
public float step3Pitch = 25f;
[Range(0f, 1f)] public float step3Alpha = 0.45f;
[Header("Step 4")]
public float step4Duration = 1.1f;
public Vector3 step4CameraLocalOffset = new Vector3(0f, -0.9f, 0.45f);
public float step4Pitch = 90f;
[Range(0f, 1f)] public float step4Alpha = 1f;
private bool sequenceStarted;
private Vector3 initialCameraLocalPos;
private Quaternion initialPivotLocalRot;
private float initialPivotPitch;
#if DOTWEEN
private Sequence sequence;
#endif
public void StartFaintSequence()
{
if (sequenceStarted) return;
sequenceStarted = true;
if (endingUIPanel != null) endingUIPanel.SetActive(false);
if (playerController == null) playerController = FindObjectOfType<Player.PlayerController>(true);
if (playerController != null) playerController.enabled = false;
if (cameraTransform == null)
{
var cam = Camera.main;
if (cam != null) cameraTransform = cam.transform;
}
if (cameraPivot == null && cameraTransform != null) cameraPivot = cameraTransform.parent;
if (cameraTransform != null) initialCameraLocalPos = cameraTransform.localPosition;
if (cameraPivot != null)
{
initialPivotLocalRot = cameraPivot.localRotation;
float x = cameraPivot.localEulerAngles.x;
if (x > 180f) x -= 360f;
initialPivotPitch = x;
}
PrepareOverlay(blackScreenCanvasGroup, setAlpha: true, alpha: 0f);
#if DOTWEEN
PlayWithDOTween();
#else
StartCoroutine(PlayWithCoroutine());
#endif
}
#if DOTWEEN
private void OnDisable()
{
if (sequence != null)
{
sequence.Kill(false);
sequence = null;
}
}
private void PlayWithDOTween()
{
if (sequence != null)
{
sequence.Kill(false);
sequence = null;
}
if (cameraTransform != null) cameraTransform.DOKill();
if (cameraPivot != null) cameraPivot.DOKill();
sequence = DOTween.Sequence();
sequence.SetUpdate(useUnscaledTime);
Vector3 step1Pos = initialCameraLocalPos + step1CameraLocalOffset;
Vector3 step3Pos = initialCameraLocalPos + step3CameraLocalOffset;
Vector3 step4Pos = initialCameraLocalPos + step4CameraLocalOffset;
if (blackScreenCanvasGroup != null)
sequence.Join(blackScreenCanvasGroup.DOFade(step1Alpha, Mathf.Max(0.0001f, step1Duration)).SetEase(alphaEase));
if (cameraTransform != null)
sequence.Join(cameraTransform.DOLocalMove(step1Pos, Mathf.Max(0.0001f, step1Duration)).SetEase(step1Ease).SetUpdate(useUnscaledTime));
if (cameraPivot != null)
sequence.Join(cameraPivot.DOLocalRotate(new Vector3(initialPivotPitch + step1Pitch, 0f, 0f), Mathf.Max(0.0001f, step1Duration), RotateMode.Fast).SetEase(step1Ease).SetUpdate(useUnscaledTime));
if (step2HoldDuration > 0f) sequence.AppendInterval(step2HoldDuration);
if (blackScreenCanvasGroup != null)
sequence.Append(blackScreenCanvasGroup.DOFade(step3Alpha, Mathf.Max(0.0001f, step3Duration)).SetEase(alphaEase));
if (cameraTransform != null)
sequence.Join(cameraTransform.DOLocalMove(step3Pos, Mathf.Max(0.0001f, step3Duration)).SetEase(step3Ease).SetUpdate(useUnscaledTime));
if (cameraPivot != null)
sequence.Join(cameraPivot.DOLocalRotate(new Vector3(initialPivotPitch + step3Pitch, 0f, 0f), Mathf.Max(0.0001f, step3Duration), RotateMode.Fast).SetEase(step3Ease).SetUpdate(useUnscaledTime));
if (blackScreenCanvasGroup != null)
sequence.Append(blackScreenCanvasGroup.DOFade(step4Alpha, Mathf.Max(0.0001f, step4Duration)).SetEase(alphaEase));
if (cameraTransform != null)
sequence.Join(cameraTransform.DOLocalMove(step4Pos, Mathf.Max(0.0001f, step4Duration)).SetEase(step4Ease).SetUpdate(useUnscaledTime));
if (cameraPivot != null)
sequence.Join(cameraPivot.DOLocalRotate(new Vector3(initialPivotPitch + step4Pitch, 0f, 0f), Mathf.Max(0.0001f, step4Duration), RotateMode.Fast).SetEase(step4Ease).SetUpdate(useUnscaledTime));
sequence.AppendCallback(FinishSequence);
}
#else
private System.Collections.IEnumerator PlayWithCoroutine()
{
yield return null;
}
#endif
private void FinishSequence()
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
if (switchToUIActionMapAtEnd && PlayerControlLockService.Instance != null)
{
PlayerControlLockService.Instance.Lock(this);
}
if (endingUIPanel != null) endingUIPanel.SetActive(true);
}
private void PrepareOverlay(CanvasGroup cg, bool setAlpha, float alpha)
{
if (cg == null) { return; }
if (!cg.gameObject.activeSelf) cg.gameObject.SetActive(true);
if (cg.transform.parent != null && !cg.transform.parent.gameObject.activeSelf) cg.transform.parent.gameObject.SetActive(true);
var animator = cg.GetComponent<Animator>();
if (animator != null) animator.enabled = false;
var reachCanvasGroupAnimator = cg.GetComponent<Michsky.UI.Reach.CanvasGroupAnimator>();
if (reachCanvasGroupAnimator != null) reachCanvasGroupAnimator.enabled = false;
var reachImageFading = cg.GetComponent<Michsky.UI.Reach.ImageFading>();
if (reachImageFading != null) reachImageFading.enabled = false;
#if DOTWEEN
cg.DOKill();
#endif
cg.interactable = false;
cg.blocksRaycasts = false;
if (setAlpha) cg.alpha = alpha;
cg.transform.SetAsLastSibling();
Canvas canvas = cg.GetComponentInParent<Canvas>(true);
if (canvas != null)
{
canvas.overrideSorting = true;
canvas.sortingOrder = 5000;
}
}
}
}