278 lines
9.7 KiB
C#
278 lines
9.7 KiB
C#
using UnityEngine;
|
|
using AibisDream.FixSystem;
|
|
using Cinemachine;
|
|
using AibisDream.Framework;
|
|
using DG.Tweening;
|
|
using System.Collections;
|
|
|
|
namespace AibisDream
|
|
{
|
|
public class CuttingManager : MonoBehaviour
|
|
{
|
|
[Header("切割组件")]
|
|
public GameObject gearFollowerPrefab;
|
|
public GameObject entrancePanelPrefab; // 入场面板预制体
|
|
public float entranceDuration = 1.5f; // 入场动画时长
|
|
public float exitDuration = 1.5f; // 退场动画时长
|
|
public float panelOffsetY = 2f; // 面板在相机视野下方的偏移量
|
|
|
|
private GearFollower gearFollower;
|
|
private bool isCuttingMode = false;
|
|
private bool isEntranceComplete = false; // 入场是否完成
|
|
private bool isGearActive = false; // 标记gear是否已激活
|
|
private BodyModule _targetModule;
|
|
private SpriteRenderer _targetSpriteRenderer;
|
|
private GameObject entrancePanel; // 入场面板实例
|
|
private Camera _mainCamera;
|
|
private CinemachineVirtualCamera _currentVirtualCamera;
|
|
|
|
private void Awake()
|
|
{
|
|
// 注册
|
|
FixSystemCenter.SystemDic.Register(this);
|
|
var virtualCam1 = transform.Find("Cut Emo Camera").GetComponent<ICinemachineCamera>();
|
|
var virtualCam2 = transform.Find("Cut Memory Camera").GetComponent<ICinemachineCamera>();
|
|
var virtualCam3 = transform.Find("Cut Logic Camera").GetComponent<ICinemachineCamera>();
|
|
var virtualCam4 = transform.Find("Cut Emo Deep Camera").GetComponent<ICinemachineCamera>();
|
|
var virtualCam5 = transform.Find("Cut Memory Deep Camera").GetComponent<ICinemachineCamera>();
|
|
var virtualCam6 = transform.Find("Cut Logic Deep Camera").GetComponent<ICinemachineCamera>();
|
|
CameraKit.Instance.RegisterCamera(CameraEnum.CutEmo, virtualCam1);
|
|
CameraKit.Instance.RegisterCamera(CameraEnum.CutMemory, virtualCam2);
|
|
CameraKit.Instance.RegisterCamera(CameraEnum.CutLogic, virtualCam3);
|
|
CameraKit.Instance.RegisterCamera(CameraEnum.CutEmoDeep, virtualCam4);
|
|
CameraKit.Instance.RegisterCamera(CameraEnum.CutMemoryDeep, virtualCam5);
|
|
CameraKit.Instance.RegisterCamera(CameraEnum.CutLogicDeep, virtualCam6);
|
|
|
|
_mainCamera = Camera.main;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (isCuttingMode && !isGearActive && gearFollower != null)
|
|
{
|
|
// 检测点击
|
|
if (Input.GetMouseButtonDown(0))
|
|
{
|
|
Ray ray = _mainCamera.ScreenPointToRay(Input.mousePosition);
|
|
RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction);
|
|
|
|
if (hit.collider != null && hit.collider.gameObject.GetComponent<GearFollower>() != null)
|
|
{
|
|
gearFollower=hit.collider.gameObject.GetComponent<GearFollower>();
|
|
ActivateGear();
|
|
}
|
|
}
|
|
}
|
|
else if (isCuttingMode && isGearActive && gearFollower != null)
|
|
{
|
|
gearFollower.GearUpdate();
|
|
}
|
|
}
|
|
|
|
private void ActivateGear()
|
|
{
|
|
isGearActive = true;
|
|
if (gearFollower != null)
|
|
{
|
|
// 解除父子关系
|
|
gearFollower.transform.SetParent(null);
|
|
gearFollower.Init(_targetSpriteRenderer);
|
|
}
|
|
|
|
// 面板退场
|
|
if (entrancePanel != null)
|
|
{
|
|
Vector3 startPosition = GetPanelSpawnPosition();
|
|
entrancePanel.transform.DOMove(startPosition, exitDuration)
|
|
.SetEase(Ease.InBack)
|
|
.OnComplete(() => {
|
|
Destroy(entrancePanel);
|
|
entrancePanel = null;
|
|
});
|
|
}
|
|
}
|
|
|
|
public IEnumerator StartCutting(BodyModule targetModule)
|
|
{
|
|
// 检查参数
|
|
if (targetModule == null)
|
|
{
|
|
Debug.LogError("targetModule 为空");
|
|
yield break;
|
|
}
|
|
|
|
// 保存目标模块
|
|
_targetModule = targetModule;
|
|
|
|
// 获取目标精灵渲染器
|
|
_targetSpriteRenderer = targetModule.GetCutSpriteRenderer();
|
|
if (_targetSpriteRenderer == null)
|
|
{
|
|
Debug.LogError("targetSprite 为空");
|
|
yield break;
|
|
}
|
|
|
|
// 停止之前的切割
|
|
StopCutting();
|
|
|
|
// 设置切割模式
|
|
isCuttingMode = true;
|
|
isEntranceComplete = false;
|
|
|
|
// 创建入场面板
|
|
CreateEntrancePanel();
|
|
|
|
// 等待入场动画完成
|
|
yield return new WaitUntil(() => isEntranceComplete);
|
|
}
|
|
|
|
private Vector3 GetPanelSpawnPosition()
|
|
{
|
|
if (_mainCamera == null)
|
|
{
|
|
_mainCamera = Camera.main;
|
|
}
|
|
|
|
|
|
// 获取相机的位置和旋转
|
|
Vector3 cameraPosition = _mainCamera.transform.position;
|
|
Quaternion cameraRotation = _mainCamera.transform.rotation;
|
|
|
|
// 计算相机视野下方的位置
|
|
Vector3 forward = cameraRotation * Vector3.forward;
|
|
Vector3 right = cameraRotation * Vector3.right;
|
|
Vector3 up = cameraRotation * Vector3.up;
|
|
|
|
// 计算相机视野的底部中心点
|
|
float height = 2f * Mathf.Tan(_mainCamera.fieldOfView * 0.5f * Mathf.Deg2Rad) * _mainCamera.nearClipPlane;
|
|
float width = height * _mainCamera.aspect;
|
|
|
|
// 计算面板的起始位置(在相机视野下方)
|
|
Vector3 bottomCenter = cameraPosition + forward * _mainCamera.nearClipPlane - up * (height * 0.5f + panelOffsetY);
|
|
|
|
return bottomCenter;
|
|
}
|
|
|
|
private void CreateEntrancePanel()
|
|
{
|
|
// 获取基于当前相机位置的生成位置
|
|
Vector3 startPosition = GetPanelSpawnPosition();
|
|
if (startPosition == Vector3.zero)
|
|
{
|
|
Debug.LogError("无法获取面板生成位置");
|
|
return;
|
|
}
|
|
|
|
// 创建入场面板,保持原始旋转
|
|
entrancePanel = Instantiate(entrancePanelPrefab, startPosition, Quaternion.Euler(0,0,-90));
|
|
|
|
// 获取GearFollower组件(作为子物体)
|
|
gearFollower = entrancePanel.GetComponentInChildren<GearFollower>();
|
|
if (gearFollower == null)
|
|
{
|
|
Debug.LogError("入场面板预制体中没有找到GearFollower组件");
|
|
return;
|
|
}
|
|
|
|
// 计算相机视野高度
|
|
float height = 2f * Mathf.Tan(_mainCamera.fieldOfView * 0.5f * Mathf.Deg2Rad) * _mainCamera.nearClipPlane;
|
|
|
|
// 计算目标位置(相机视野中心偏下)
|
|
Vector3 targetPosition = startPosition + _mainCamera.transform.up * 3.5f;
|
|
|
|
// 执行入场动画
|
|
entrancePanel.transform.DOMove(targetPosition, entranceDuration)
|
|
.SetEase(Ease.OutBack)
|
|
.OnComplete(() => {
|
|
isEntranceComplete = true;
|
|
});
|
|
}
|
|
|
|
public void OnCutComplete()
|
|
{
|
|
isCuttingMode = false;
|
|
isEntranceComplete = false;
|
|
isGearActive = false;
|
|
|
|
if (gearFollower != null)
|
|
{
|
|
gearFollower.FinishCutting();
|
|
}
|
|
|
|
// 如果面板还存在,删除它
|
|
if (entrancePanel != null)
|
|
{
|
|
Destroy(entrancePanel);
|
|
entrancePanel = null;
|
|
}
|
|
}
|
|
public void UpdateModule()
|
|
{
|
|
if (_targetModule != null)
|
|
{
|
|
_targetModule.OnCuttingDown();
|
|
}
|
|
}
|
|
public void SetCutTextVisible(bool visible)
|
|
{
|
|
if (_targetModule != null)
|
|
{
|
|
_targetModule.SetCutTextVisible(visible);
|
|
}
|
|
}
|
|
|
|
public void UpdateCutProgress(float progress)
|
|
{
|
|
if (_targetModule != null)
|
|
{
|
|
_targetModule.UpdateCutProgress(progress);
|
|
}
|
|
}
|
|
public void StartCutTextFlicker()
|
|
{
|
|
if (_targetModule != null)
|
|
{
|
|
_targetModule.StartCutTextFlicker();
|
|
}
|
|
}
|
|
public void StopCutTextFlicker()
|
|
{
|
|
if (_targetModule != null)
|
|
{
|
|
_targetModule.StopCutTextFlicker();
|
|
}
|
|
}
|
|
|
|
public void StopCutting()
|
|
{
|
|
isCuttingMode = false;
|
|
isEntranceComplete = false;
|
|
isGearActive = false;
|
|
|
|
if (_targetModule != null)
|
|
{
|
|
_targetModule.StopCutTextFlicker();
|
|
}
|
|
|
|
if (entrancePanel != null)
|
|
{
|
|
// 获取当前相机位置
|
|
Vector3 startPosition = GetPanelSpawnPosition();
|
|
|
|
// 执行退场动画
|
|
entrancePanel.transform.DOMove(startPosition, exitDuration)
|
|
.SetEase(Ease.InBack)
|
|
.OnComplete(() => {
|
|
Destroy(entrancePanel);
|
|
entrancePanel = null;
|
|
gearFollower = null;
|
|
});
|
|
}
|
|
else if (gearFollower != null)
|
|
{
|
|
Destroy(gearFollower.gameObject);
|
|
gearFollower = null;
|
|
}
|
|
}
|
|
}
|
|
} |