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(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(); if (animator != null) animator.enabled = false; var reachCanvasGroupAnimator = cg.GetComponent(); if (reachCanvasGroupAnimator != null) reachCanvasGroupAnimator.enabled = false; var reachImageFading = cg.GetComponent(); 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(true); if (canvas != null) { canvas.overrideSorting = true; canvas.sortingOrder = 5000; } } } }