using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Unity.Mathematics; using UnityEngine; using UnityEngine.Events; using UnityEngine.InputSystem; public class SceneTransitionManager : MonoSingleton { public Camera MainCamera; public List TransitionPoints = new(); public List TransitionFOV = new(); public int CurrentTrackingPointIndex = 0; public float ScrollingSpeed = 1; public Transform CameraLeftBound; public Transform CameraRightBound; public MHCInputActions MHCInput; //向外从神谱出发分别为 3 - 2 - 1 - 0 public float ScrollingInput = 0; public Action ShenPuStyle;//神谱进出事件 public UnityEvent OnTransition; private AudioSource ac; private bool isTimelineActive = false; // 标志是否Timeline正在控制相机 public override void Awake() { base.Awake(); } public void Start() { MHCInput = new MHCInputActions(); MHCInput.Game.ScrollingScene.performed += context => ScrollingInput = context.action.ReadValue(); MHCInput.Game.ScrollingScene.canceled += context => ScrollingInput = 0; MHCInput.Game.SwitchScene.started += OnSwitchUp; MHCInput.Enable(); if (TransitionFOV.Count < TransitionPoints.Count) { TransitionFOV = (from t in TransitionPoints select 60.0f).ToList(); } ac = GetComponent(); } public void SideScrolling(float speed) { var position = TransitionPoints[CurrentTrackingPointIndex].position; var currentDistanceToBoundary = 0f; currentDistanceToBoundary = speed < 0 ? Mathf.Abs(position.x - CameraLeftBound.position.x) : Mathf.Abs(position.x - CameraRightBound.position.x); var maxDistanceToBoundary = Mathf.Abs(CameraLeftBound.position.x - CameraRightBound.position.x) * 0.5f; var actualScrollingSpeed = Mathf.Min(ScrollingSpeed * currentDistanceToBoundary / (0.2f * maxDistanceToBoundary), ScrollingSpeed); // print(actualScrollingSpeed); TransitionPoints[CurrentTrackingPointIndex].position += TransitionPoints[CurrentTrackingPointIndex].right * (speed * Time.deltaTime * actualScrollingSpeed); // print(TransitionPoints[CurrentTrackingPointIndex].right * speed * Time.deltaTime * actualScrollingSpeed); // CameraStyle = Camerachange; } public void Update() { if (isTimelineActive) { SideScrolling(ScrollingInput); } else { SideScrolling(ScrollingInput); CurrentTrackingPointIndex = math.clamp(CurrentTrackingPointIndex, 0, TransitionPoints.Count - 1); MainCamera.transform.position = Vector3.Lerp(MainCamera.transform.position, TransitionPoints[CurrentTrackingPointIndex].position, 0.1f); MainCamera.transform.rotation = Quaternion.Lerp(MainCamera.transform.rotation, TransitionPoints[CurrentTrackingPointIndex].rotation, 0.1f); MainCamera.fieldOfView = Mathf.Lerp(MainCamera.fieldOfView, TransitionFOV[CurrentTrackingPointIndex], 0.1f); ShenPuStyle?.Invoke(); } } public void OnSwitchUp(InputAction.CallbackContext context) { // Debug.Log(CurrentTrackingPointIndex); if (!context.started) return; if (CurrentTrackingPointIndex == TransitionPoints.Count) return; int preIndex = CurrentTrackingPointIndex; var wheel = context.action.ReadValue(); CurrentTrackingPointIndex += (int)(wheel / math.abs(wheel)); //神谱单独进入 CurrentTrackingPointIndex = Mathf.Clamp(CurrentTrackingPointIndex, 0, TransitionPoints.Count - 1); OnTransition.Invoke(CurrentTrackingPointIndex); if (CurrentTrackingPointIndex == (TransitionPoints.Count - 1)) { ShenPuStyle = InShenPu; } else { if (preIndex > CurrentTrackingPointIndex) ac.PlayOneShot(Singleton.Instance.BackwardSceneSound); else ac.PlayOneShot(Singleton.Instance.ForwardSceneSound); } } /// /// 进入或者退出神谱 /// public void TriggerShenPu() { if (CurrentTrackingPointIndex == TransitionPoints.Count - 1) { //在神谱界面时 FindObjectOfType().ExitTreeScreen(); TransitionPoints[CurrentTrackingPointIndex].gameObject.SetActive(false); CurrentTrackingPointIndex = TransitionPoints.Count - 2; } else { //进入神谱界面 CurrentTrackingPointIndex = TransitionPoints.Count - 1; TransitionPoints[CurrentTrackingPointIndex].gameObject.SetActive(true); } OnTransition.Invoke(CurrentTrackingPointIndex); } public void InShenPu() { if (CurrentTrackingPointIndex != (TransitionPoints.Count - 1)) { ShenPuStyle = null; } if (Vector3.Distance(MainCamera.transform.position, TransitionPoints[TransitionPoints.Count - 1].position) < 0.5f) { MainCamera.transform.position = TransitionPoints[CurrentTrackingPointIndex].position; TransitionPoints[CurrentTrackingPointIndex].gameObject.SetActive(true); OnTransition.Invoke(CurrentTrackingPointIndex); ShenPuStyle = DeShenPu; } } private void DeShenPu() { if (CurrentTrackingPointIndex != (TransitionPoints.Count - 1)) { FindObjectOfType().ExitTreeScreen(); TransitionPoints[CurrentTrackingPointIndex].gameObject.SetActive(false); ShenPuStyle = null; } } public GameObject YishiCamera; public Vector3 Layer12Diff = new Vector3(1, 1, 1); public void TransitionToPoint() { StartCoroutine(ExecuteEveryFrameForOneSecond()); isTimelineActive = true; // 标记Timeline控制相机 } public void RestoreCameraControl() { isTimelineActive = false; // 重新恢复鼠标控制 } IEnumerator ExecuteEveryFrameForOneSecond() { float elapsedTime = 0f; while (elapsedTime < 1f) // 1秒 { MainCamera.transform.position = Vector3.Lerp(MainCamera.transform.position, YishiCamera.transform.position, 0.1f); MainCamera.transform.rotation = Quaternion.Lerp(MainCamera.transform.rotation, YishiCamera.transform.rotation, 0.1f); // 增加经过时间 elapsedTime += Time.deltaTime; // 等待下一帧 yield return null; } YiShiUI.Instance.OnPlayableDirectorStopped(); // 协程结束后的逻辑 Debug.Log("协程结束"); RestoreCameraControl(); } }