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 CameraController : MonoBehaviour { 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("습격모드 카메라를 넣어주세요.")] [field: SerializeField] public CinemachineFreeLook AssaultCam { get; set; } [Required("보트갑판 카메라를 넣어주세요.")] public CinemachineVirtualCamera shipDeckCam; [Required("조준 카메라를 넣어주세요.")] public CinemachineFreeLook takeAimCam; [Required("보트안 카메라를 넣어주세요.")] public CinemachineVirtualCamera inShipCam; public float sensitivity = 0.01f; [MinMaxSlider(2, 50, true)] public Vector2 heightLimits = new Vector2(2, 50); private void Awake() { MainCam = Camera.main; } private void Start() { dredgeCamOrbitalTransposer = dredgeCam.GetCinemachineComponent(); } private void Update() { TakeCamMovement(); DredgeCamRotate(); AssaultCamRotate(); } public void CamAssaultMode() { AssaultCam.Priority = 1; dredgeCam.Priority = 0; shipDeckCam.Priority = 0; inShipCam.Priority = 0; } public void CamDredgeMode() { dredgeCam.Priority = 1; AssaultCam.Priority = 0; shipDeckCam.Priority = 0; inShipCam.Priority = 0; } public void CamShipDeckMode() { shipDeckCam.Priority = 1; dredgeCam.Priority = 0; AssaultCam.Priority = 0; inShipCam.Priority = 0; } public void CamInShipMode() { inShipCam.Priority = 1; dredgeCam.Priority = 0; AssaultCam.Priority = 0; shipDeckCam.Priority = 0; } private void TakeCamMovement() { Vector2 mouseDelta = Mouse.current.delta.ReadValue(); Vector3 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 AssaultCamRotate() { if (Input.GetMouseButtonDown(1)) { //AssaultCam의 X Axis의 Speed를 변경 AssaultCam.m_XAxis.m_MaxSpeed = 150; AssaultCam.m_XAxis.m_InputAxisName = "Mouse X"; //AssaultCam의 Y Axis의 Speed를 변경 AssaultCam.m_YAxis.m_MaxSpeed = 2; AssaultCam.m_YAxis.m_InputAxisName = "Mouse Y"; AssaultCam.m_RecenterToTargetHeading.m_enabled = false; } else if (Input.GetMouseButtonUp(1)) { //AssaultCam의 X Axis의 Speed를 원래대로 AssaultCam.m_XAxis.m_MaxSpeed = 0; AssaultCam.m_XAxis.m_InputAxisName = ""; //AssaultCam의 Y Axis의 Speed를 원래대로 AssaultCam.m_YAxis.m_MaxSpeed = 0; AssaultCam.m_YAxis.m_InputAxisName = ""; AssaultCam.m_RecenterToTargetHeading.m_enabled = true; } } public void ChangeInShipFollowOffset() { if (!GameManager.Inst.IsInShipMode) return; Vector3 targetOffset = new Vector3(0, 7, -10); StartSmoothTransition(targetOffset); } public void RestoreInShipFollowOffset() { if (!GameManager.Inst.IsInShipMode) return; Vector3 targetOffset = new Vector3(0, 20, -10); StartSmoothTransition(targetOffset); } private void StartSmoothTransition(Vector3 targetOffset) { if (currentCoroutine != null) { StopCoroutine(currentCoroutine); } currentCoroutine = StartCoroutine(SmoothTransition(targetOffset)); } private IEnumerator SmoothTransition(Vector3 targetOffset) { var transposer = inShipCam.GetCinemachineComponent(); if (transposer != null) { var elapsedTime = 0f; var duration = .25f; // 이 값은 원하는 대로 설정하십시오. 이 값은 전환에 걸리는 시간을 결정합니다. var startingOffset = transposer.m_FollowOffset; while (elapsedTime < duration) { transposer.m_FollowOffset = Vector3.Lerp(startingOffset, targetOffset, elapsedTime / duration); elapsedTime += Time.deltaTime; yield return null; } transposer.m_FollowOffset = targetOffset; // Lerp가 완료되면 목표 오프셋을 확실히 설정합니다. } } } }