MayHeCome/Assets/Scripts/SceneTransitionManager.cs
2024-12-18 17:55:34 +08:00

200 lines
6.8 KiB
C#

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<SceneTransitionManager>
{
public Camera MainCamera;
public List<Transform> TransitionPoints = new();
public List<float> 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<int> 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<float>();
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<AudioSource>();
}
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<float>();
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<AudioManager>.Instance.BackwardSceneSound);
else ac.PlayOneShot(Singleton<AudioManager>.Instance.ForwardSceneSound);
}
}
/// <summary>
/// 进入或者退出神谱
/// </summary>
public void TriggerShenPu()
{
if (CurrentTrackingPointIndex == TransitionPoints.Count - 1)
{
//在神谱界面时
FindObjectOfType<Move>().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<Move>().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();
}
}