using System; using System.Collections; using Cinemachine; using Sirenix.OdinInspector; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.Serialization; // ReSharper disable once CheckNamespace namespace BlueWaterProject { public class CameraManager : Singleton { public Camera MainCam { get; private set; } [Title("Dredge Cam")] [Required("드렛지 카메라를 넣어주세요.")] public CinemachineVirtualCamera dredgeCam; private CinemachineOrbitalTransposer dredgeCamOrbitalTransposer; [Range(0,1000)] public int rotateSpeed = 10; private Coroutine currentCoroutine; [Required("보트갑판 카메라를 넣어주세요.")] public CinemachineVirtualCamera shipDeckCam; [Required("조준 카메라를 넣어주세요.")] public CinemachineFreeLook takeAimCam; [Required("보트안 카메라를 넣어주세요.")] public CinemachineVirtualCamera inShipCam; private Vector3 inShipCamOrigenalOffset; public float sensitivity = 0.01f; [MinMaxSlider(2, 50, true)] public Vector2 heightLimits = new Vector2(2, 50); [Title("InShip Change Offset")] private Vector3 targetOffset; private Vector3 startingOffset; private float elapsedTime = 0; private float duration = 0.5f; private bool isTransitioning = false; protected override void OnAwake() { MainCam = Camera.main; inShipCamOrigenalOffset = inShipCam.GetCinemachineComponent().m_FollowOffset; } private void Start() { dredgeCamOrbitalTransposer = dredgeCam.GetCinemachineComponent(); } private void Update() { TakeCamMovement(); DredgeCamRotate(); } private void FixedUpdate() { if (isTransitioning) { SmoothTransitionFixedUpdate(); } } public void CamAssaultMode() { dredgeCam.Priority = 0; shipDeckCam.Priority = 0; inShipCam.Priority = 0; } public void CamDredgeMode() { dredgeCam.Priority = 1; shipDeckCam.Priority = 0; inShipCam.Priority = 0; } public void CamShipDeckMode() { shipDeckCam.Priority = 1; dredgeCam.Priority = 0; inShipCam.Priority = 0; } public void CamInShipMode() { inShipCam.Priority = 1; dredgeCam.Priority = 0; shipDeckCam.Priority = 0; } private void TakeCamMovement() { var mouseDelta = Mouse.current.delta.ReadValue(); var newPosition = takeAimCam.transform.position; newPosition.y += mouseDelta.y * sensitivity; newPosition.y = Mathf.Clamp(newPosition.y, heightLimits.x, heightLimits.y); newPosition.x = GameManager.Inst.ShipPlayer.transform.position.x; newPosition.z = GameManager.Inst.ShipPlayer.transform.position.z; takeAimCam.transform.position = newPosition; // Rotate around Y axis (Up direction) takeAimCam.transform.RotateAround(takeAimCam.transform.position, Vector3.up, mouseDelta.x * sensitivity); } public void CamTakeAim(bool isTakeAim) { takeAimCam.Priority = isTakeAim ? 2 : 0; float yRotation = dredgeCam.transform.rotation.eulerAngles.y; takeAimCam.transform.rotation = Quaternion.Euler(takeAimCam.transform.rotation.eulerAngles.x, yRotation, takeAimCam.transform.rotation.eulerAngles.z); } private void DredgeCamRotate() { if (Input.GetMouseButtonDown(1)) { //dredgeCam의 X Axis의 Speed를 변경 dredgeCamOrbitalTransposer.m_XAxis.m_MaxSpeed = rotateSpeed; dredgeCamOrbitalTransposer.m_XAxis.m_InputAxisName = "Mouse X"; dredgeCamOrbitalTransposer.m_RecenterToTargetHeading.m_enabled = false; } else if (Input.GetMouseButtonUp(1)) { //dredgeCam의 X Axis의 Speed를 원래대로 dredgeCamOrbitalTransposer.m_XAxis.m_MaxSpeed = 0; dredgeCamOrbitalTransposer.m_XAxis.m_InputAxisName = ""; dredgeCamOrbitalTransposer.m_RecenterToTargetHeading.m_enabled = true; } } private void StartSmoothTransition(Vector3 newTargetOffset) { targetOffset = newTargetOffset; var transposer = inShipCam.GetCinemachineComponent(); if (transposer != null) { startingOffset = transposer.m_FollowOffset; } elapsedTime = 0; isTransitioning = true; } private void SmoothTransitionFixedUpdate() { var transposer = inShipCam.GetCinemachineComponent(); if (transposer != null) { if (elapsedTime < duration) { elapsedTime += Time.fixedDeltaTime; float t = elapsedTime / duration; transposer.m_FollowOffset = Vector3.Lerp(startingOffset, targetOffset, t); } else { transposer.m_FollowOffset = targetOffset; isTransitioning = false; } } } public void ChangeInShipFollowAndLookAt(Transform target) { if (!GameManager.Inst.IsInShipMode) return; inShipCam.Follow = target; inShipCam.LookAt = target; var targetOffset = new Vector3(0, 9, -10); StartSmoothTransition(targetOffset); } public void RestoreInShipFollowAndLookAt() { if (!GameManager.Inst.IsInShipMode) return; var transform1 = GameManager.Inst.InShipPlayer.transform; inShipCam.Follow = transform1; inShipCam.LookAt = transform1; var targetOffset = inShipCamOrigenalOffset; StartSmoothTransition(targetOffset); } } }