ADD : 카메라 스크립트 파일 업로드
This commit is contained in:
parent
cd6c31f54a
commit
01c3eb04e8
@ -1,10 +1,10 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Unity.Cinemachine;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityRawInput;
|
using UnityRawInput;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Unity.Cinemachine;
|
||||||
|
|
||||||
public class CameraManager : MonoBehaviour
|
public class CameraManager : MonoBehaviour, IController
|
||||||
{
|
{
|
||||||
#region Classes
|
#region Classes
|
||||||
private static class KeyMapping
|
private static class KeyMapping
|
||||||
@ -66,7 +66,6 @@ public class CameraManager : MonoBehaviour
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 현재 눌린 키 확인
|
|
||||||
foreach (KeyCode keyCode in System.Enum.GetValues(typeof(KeyCode)))
|
foreach (KeyCode keyCode in System.Enum.GetValues(typeof(KeyCode)))
|
||||||
{
|
{
|
||||||
if (Input.GetKeyDown(keyCode) && KeyMapping.TryGetRawKey(keyCode, out RawKey rawKey))
|
if (Input.GetKeyDown(keyCode) && KeyMapping.TryGetRawKey(keyCode, out RawKey rawKey))
|
||||||
@ -78,7 +77,6 @@ public class CameraManager : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 모든 키가 떼어졌는지 확인
|
|
||||||
bool allKeysReleased = rawKeys.Any() && rawKeys.All(key => !Input.GetKey(KeyMapping.TryGetKeyCode(key, out KeyCode keyCode) ? keyCode : KeyCode.None));
|
bool allKeysReleased = rawKeys.Any() && rawKeys.All(key => !Input.GetKey(KeyMapping.TryGetKeyCode(key, out KeyCode keyCode) ? keyCode : KeyCode.None));
|
||||||
|
|
||||||
if (allKeysReleased)
|
if (allKeysReleased)
|
||||||
@ -89,9 +87,6 @@ public class CameraManager : MonoBehaviour
|
|||||||
|
|
||||||
public void InitializeUnityKeys()
|
public void InitializeUnityKeys()
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
unityKeys ??= new List<KeyCode>();
|
|
||||||
unityKeys.Clear();
|
unityKeys.Clear();
|
||||||
|
|
||||||
if (rawKeys == null || !rawKeys.Any()) return;
|
if (rawKeys == null || !rawKeys.Any()) return;
|
||||||
@ -104,45 +99,23 @@ public class CameraManager : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (System.Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError($"핫키 초기화 중 오류 발생: {e.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsTriggered()
|
public bool IsTriggered()
|
||||||
{
|
{
|
||||||
if (isRecording) return false;
|
if (isRecording) return false;
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (rawKeys == null || !rawKeys.Any()) return false;
|
if (rawKeys == null || !rawKeys.Any()) return false;
|
||||||
|
|
||||||
// RawInput으로 체크 (우선순위)
|
|
||||||
bool allRawKeysPressed = rawKeys.All(key => RawInput.IsKeyDown(key));
|
bool allRawKeysPressed = rawKeys.All(key => RawInput.IsKeyDown(key));
|
||||||
if (allRawKeysPressed)
|
if (allRawKeysPressed) return true;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unity Input으로 체크 (백업)
|
if (unityKeys.Any())
|
||||||
if (unityKeys != null && unityKeys.Any())
|
|
||||||
{
|
{
|
||||||
bool allKeysPressed = unityKeys.All(key => Input.GetKey(key));
|
return unityKeys.All(key => Input.GetKey(key));
|
||||||
if (allKeysPressed)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (System.Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError($"핫키 트리거 확인 중 오류 발생: {e.Message}");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() =>
|
public override string ToString() =>
|
||||||
rawKeys?.Any() == true ? string.Join(" + ", rawKeys) : "설정되지 않음";
|
rawKeys?.Any() == true ? string.Join(" + ", rawKeys) : "설정되지 않음";
|
||||||
@ -176,15 +149,22 @@ public class CameraManager : MonoBehaviour
|
|||||||
[SerializeField] public List<CameraPreset> cameraPresets = new List<CameraPreset>();
|
[SerializeField] public List<CameraPreset> cameraPresets = new List<CameraPreset>();
|
||||||
|
|
||||||
[Header("Camera Control Settings")]
|
[Header("Camera Control Settings")]
|
||||||
[SerializeField, Range(0.1f, 10f)] private float rotationSensitivity = 2f;
|
private float rotationSensitivity = 2f;
|
||||||
[SerializeField, Range(0.1f, 20f)] private float panSpeed = 10f;
|
private float panSpeed = 0.02f;
|
||||||
[SerializeField, Range(0.1f, 20f)] private float zoomSpeed = 10f;
|
private float zoomSpeed = 0.1f;
|
||||||
[SerializeField, Range(0.1f, 10f)] private float orbitSpeed = 5f;
|
private float orbitSpeed = 10f;
|
||||||
|
|
||||||
private CinemachineCamera currentCamera;
|
private CinemachineCamera currentCamera;
|
||||||
private InputHandler inputHandler;
|
private InputHandler inputHandler;
|
||||||
private Vector3 targetPosition;
|
|
||||||
private CameraPreset currentPreset;
|
private CameraPreset currentPreset;
|
||||||
|
private Vector3 rotationCenter = Vector3.zero;
|
||||||
|
private Vector3 rotationStartPosition;
|
||||||
|
private bool isRotating = false;
|
||||||
|
|
||||||
|
// 초기 카메라 상태 저장
|
||||||
|
private Vector3 initialPosition;
|
||||||
|
private Quaternion initialRotation;
|
||||||
|
private bool isInitialStateSet = false;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
@ -194,28 +174,18 @@ public class CameraManager : MonoBehaviour
|
|||||||
|
|
||||||
#region Unity Messages
|
#region Unity Messages
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
InitializeInputHandler();
|
InitializeInputHandler();
|
||||||
InitializeRawInput();
|
InitializeRawInput();
|
||||||
InitializeCameraPresets();
|
InitializeCameraPresets();
|
||||||
}
|
}
|
||||||
catch (System.Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError($"초기화 중 오류 발생: {e.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
try
|
if (RawInput.IsRunning)
|
||||||
{
|
{
|
||||||
CleanupRawInput();
|
RawInput.OnKeyDown -= HandleRawKeyDown;
|
||||||
}
|
RawInput.Stop();
|
||||||
catch (System.Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError($"정리 중 오류 발생: {e.Message}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,16 +193,9 @@ public class CameraManager : MonoBehaviour
|
|||||||
{
|
{
|
||||||
if (!IsValidSetup) return;
|
if (!IsValidSetup) return;
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
UpdateHotkeyRecording();
|
UpdateHotkeyRecording();
|
||||||
HandleCameraControls();
|
HandleCameraControls();
|
||||||
HandleUnityHotkeys();
|
HandleHotkeys();
|
||||||
}
|
|
||||||
catch (System.Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError($"카메라 제어 중 오류 발생: {e.Message}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateHotkeyRecording()
|
private void UpdateHotkeyRecording()
|
||||||
@ -254,7 +217,6 @@ public class CameraManager : MonoBehaviour
|
|||||||
if (inputHandler == null)
|
if (inputHandler == null)
|
||||||
{
|
{
|
||||||
inputHandler = gameObject.AddComponent<InputHandler>();
|
inputHandler = gameObject.AddComponent<InputHandler>();
|
||||||
Debug.Log("InputHandler 컴포넌트가 자동으로 추가되었습니다.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +227,7 @@ public class CameraManager : MonoBehaviour
|
|||||||
RawInput.Start();
|
RawInput.Start();
|
||||||
RawInput.WorkInBackground = true;
|
RawInput.WorkInBackground = true;
|
||||||
}
|
}
|
||||||
RawInput.OnKeyDown += HandleKeyDown;
|
RawInput.OnKeyDown += HandleRawKeyDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeCameraPresets()
|
private void InitializeCameraPresets()
|
||||||
@ -273,12 +235,10 @@ public class CameraManager : MonoBehaviour
|
|||||||
if (cameraPresets == null)
|
if (cameraPresets == null)
|
||||||
{
|
{
|
||||||
cameraPresets = new List<CameraPreset>();
|
cameraPresets = new List<CameraPreset>();
|
||||||
Debug.LogWarning("카메라 프리셋 리스트가 null이어서 새로 생성되었습니다.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cameraPresets.Any())
|
if (!cameraPresets.Any())
|
||||||
{
|
{
|
||||||
Debug.LogWarning("카메라 프리셋이 설정되어 있지 않습니다.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,57 +247,47 @@ public class CameraManager : MonoBehaviour
|
|||||||
preset.hotkey.InitializeUnityKeys();
|
preset.hotkey.InitializeUnityKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitchToCamera(0);
|
Set(0);
|
||||||
}
|
|
||||||
|
|
||||||
private void CleanupRawInput()
|
// 초기 카메라 상태 저장
|
||||||
|
if (currentCamera != null && !isInitialStateSet)
|
||||||
{
|
{
|
||||||
if (RawInput.IsRunning)
|
initialPosition = currentCamera.transform.position;
|
||||||
{
|
initialRotation = currentCamera.transform.rotation;
|
||||||
RawInput.OnKeyDown -= HandleKeyDown;
|
isInitialStateSet = true;
|
||||||
RawInput.Stop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Input Handling
|
#region Input Handling
|
||||||
private void HandleKeyDown(RawKey key)
|
private void HandleRawKeyDown(RawKey key)
|
||||||
{
|
{
|
||||||
if (key == default(RawKey)) return;
|
if (key == default(RawKey)) return;
|
||||||
TryActivatePresetByInput(preset =>
|
TryActivatePresetByInput(preset =>
|
||||||
{
|
|
||||||
if (preset?.hotkey == null) return false;
|
|
||||||
bool contains = preset.hotkey.rawKeys?.Contains(key) == true;
|
|
||||||
bool triggered = preset.hotkey.IsTriggered();
|
|
||||||
return contains && triggered;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleUnityHotkeys()
|
|
||||||
{
|
|
||||||
if (!Input.anyKeyDown) return;
|
|
||||||
TryActivatePresetByInput(preset =>
|
|
||||||
{
|
{
|
||||||
if (preset?.hotkey == null) return false;
|
if (preset?.hotkey == null) return false;
|
||||||
return preset.hotkey.IsTriggered();
|
return preset.hotkey.IsTriggered();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleHotkeys()
|
||||||
|
{
|
||||||
|
if (Input.anyKeyDown)
|
||||||
|
{
|
||||||
|
TryActivatePresetByInput(preset =>
|
||||||
|
{
|
||||||
|
if (preset?.hotkey == null) return false;
|
||||||
|
return preset.hotkey.IsTriggered();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void TryActivatePresetByInput(System.Func<CameraPreset, bool> predicate)
|
private void TryActivatePresetByInput(System.Func<CameraPreset, bool> predicate)
|
||||||
{
|
{
|
||||||
try
|
var matchingPreset = cameraPresets?.FirstOrDefault(predicate);
|
||||||
{
|
|
||||||
var matchingPreset = cameraPresets?
|
|
||||||
.FirstOrDefault(predicate);
|
|
||||||
|
|
||||||
if (matchingPreset != null)
|
if (matchingPreset != null)
|
||||||
{
|
{
|
||||||
SwitchToCamera(cameraPresets.IndexOf(matchingPreset));
|
Set(cameraPresets.IndexOf(matchingPreset));
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (System.Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError($"프리셋 활성화 중 오류 발생: {e.Message}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -347,137 +297,175 @@ public class CameraManager : MonoBehaviour
|
|||||||
{
|
{
|
||||||
if (!IsValidSetup) return;
|
if (!IsValidSetup) return;
|
||||||
|
|
||||||
Transform cameraTransform = currentCamera.transform;
|
var virtualCamera = currentCamera;
|
||||||
if (cameraTransform == null) return;
|
if (virtualCamera == null) return;
|
||||||
|
|
||||||
HandleRotation(cameraTransform);
|
// Alt+Q로 초기 위치로 복원
|
||||||
HandlePanning(cameraTransform);
|
if (Input.GetKey(KeyCode.LeftAlt) && Input.GetKeyDown(KeyCode.Q))
|
||||||
HandleZooming(cameraTransform);
|
{
|
||||||
HandleOrbiting(cameraTransform);
|
RestoreInitialCameraState();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleRotation(Transform cameraTransform)
|
HandleRotation(virtualCamera);
|
||||||
|
HandlePanning(virtualCamera);
|
||||||
|
HandleZooming(virtualCamera);
|
||||||
|
HandleOrbiting(virtualCamera);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleRotation(CinemachineCamera virtualCamera)
|
||||||
{
|
{
|
||||||
if (!inputHandler.IsRightMouseHeld()) return;
|
Transform cameraTransform = virtualCamera.transform;
|
||||||
|
|
||||||
|
if (inputHandler.IsRightMouseHeld())
|
||||||
|
{
|
||||||
|
if (!isRotating)
|
||||||
|
{
|
||||||
|
// 회전 시작 시 현재 위치 저장
|
||||||
|
isRotating = true;
|
||||||
|
rotationStartPosition = cameraTransform.position;
|
||||||
|
// 현재 카메라의 y값을 기준으로 회전 중심점 설정
|
||||||
|
rotationCenter = new Vector3(0f, rotationStartPosition.y, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 lookDelta = inputHandler.GetLookDelta();
|
Vector2 lookDelta = inputHandler.GetLookDelta();
|
||||||
if (lookDelta.sqrMagnitude < float.Epsilon) return;
|
if (lookDelta.sqrMagnitude < float.Epsilon) return;
|
||||||
|
|
||||||
var rotation = new Vector3(-lookDelta.y, lookDelta.x, 0f) * rotationSensitivity;
|
// 현재 회전값을 오일러 각도로 가져오기
|
||||||
cameraTransform.rotation *= Quaternion.Euler(rotation);
|
Vector3 currentEuler = cameraTransform.eulerAngles;
|
||||||
|
|
||||||
|
// X축 회전값을 -80도에서 80도 사이로 제한하기 위해 360도 형식에서 변환
|
||||||
|
float currentX = currentEuler.x;
|
||||||
|
if (currentX > 180f) currentX -= 360f;
|
||||||
|
|
||||||
|
// 새로운 회전값 계산
|
||||||
|
float newX = currentX - lookDelta.y * rotationSensitivity;
|
||||||
|
float newY = currentEuler.y + lookDelta.x * rotationSensitivity;
|
||||||
|
|
||||||
|
// X축 회전 제한 (-80도 ~ 80도)
|
||||||
|
newX = Mathf.Clamp(newX, -80f, 80f);
|
||||||
|
|
||||||
|
// 회전 적용
|
||||||
|
Quaternion targetRotation = Quaternion.Euler(newX, newY, 0f);
|
||||||
|
cameraTransform.rotation = targetRotation;
|
||||||
|
|
||||||
|
// 회전 시작 위치를 기준으로 회전 (y값 유지)
|
||||||
|
Vector3 relativePosition = rotationStartPosition - rotationCenter;
|
||||||
|
Vector3 rotatedPosition = targetRotation * new Vector3(relativePosition.x, 0f, relativePosition.z);
|
||||||
|
Vector3 newPosition = rotationCenter + rotatedPosition;
|
||||||
|
cameraTransform.position = newPosition;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isRotating = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandlePanning(Transform cameraTransform)
|
private void HandlePanning(CinemachineCamera virtualCamera)
|
||||||
{
|
{
|
||||||
if (!inputHandler.IsMiddleMouseHeld()) return;
|
if (!inputHandler.IsMiddleMouseHeld()) return;
|
||||||
|
|
||||||
Vector2 panDelta = inputHandler.GetLookDelta();
|
Vector2 panDelta = inputHandler.GetLookDelta();
|
||||||
if (panDelta.sqrMagnitude < float.Epsilon) return;
|
if (panDelta.sqrMagnitude < float.Epsilon) return;
|
||||||
|
|
||||||
Vector3 panMovement =
|
Transform cameraTransform = virtualCamera.transform;
|
||||||
cameraTransform.right * -panDelta.x * panSpeed +
|
|
||||||
cameraTransform.up * -panDelta.y * panSpeed;
|
// 이동 적용 (카메라의 right와 up 방향으로 이동)
|
||||||
cameraTransform.position += panMovement * Time.deltaTime;
|
Vector3 right = cameraTransform.right * -panDelta.x * panSpeed;
|
||||||
|
Vector3 up = cameraTransform.up * -panDelta.y * panSpeed;
|
||||||
|
|
||||||
|
cameraTransform.position += right + up;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleZooming(Transform cameraTransform)
|
private void HandleZooming(CinemachineCamera virtualCamera)
|
||||||
{
|
{
|
||||||
|
if (inputHandler.IsZoomActive())
|
||||||
|
{
|
||||||
|
// Ctrl + 좌클릭으로 줌
|
||||||
|
Vector2 lookDelta = inputHandler.GetLookDelta();
|
||||||
|
if (lookDelta.sqrMagnitude < float.Epsilon) return;
|
||||||
|
|
||||||
|
Transform cameraTransform = virtualCamera.transform;
|
||||||
|
Vector3 forward = cameraTransform.forward * lookDelta.y * zoomSpeed * 10f;
|
||||||
|
cameraTransform.position += forward;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 마우스 휠로 줌
|
||||||
float zoomDelta = inputHandler.GetZoomDelta();
|
float zoomDelta = inputHandler.GetZoomDelta();
|
||||||
if (Mathf.Abs(zoomDelta) <= 0.1f) return;
|
if (Mathf.Abs(zoomDelta) <= 0.1f) return;
|
||||||
|
|
||||||
cameraTransform.position += cameraTransform.forward * zoomDelta * zoomSpeed * Time.deltaTime;
|
Transform cameraTransform = virtualCamera.transform;
|
||||||
|
Vector3 forward = cameraTransform.forward * zoomDelta * zoomSpeed;
|
||||||
|
cameraTransform.position += forward;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleOrbiting(Transform cameraTransform)
|
private void HandleOrbiting(CinemachineCamera virtualCamera)
|
||||||
{
|
{
|
||||||
if (!inputHandler.IsOrbitActive()) return;
|
if (!inputHandler.IsOrbitActive()) return;
|
||||||
|
|
||||||
if (inputHandler.IsOrbitStarting())
|
|
||||||
{
|
|
||||||
UpdateOrbitTarget(cameraTransform);
|
|
||||||
}
|
|
||||||
|
|
||||||
PerformOrbitRotation(cameraTransform);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateOrbitTarget(Transform cameraTransform)
|
|
||||||
{
|
|
||||||
if (Camera.main == null)
|
|
||||||
{
|
|
||||||
targetPosition = cameraTransform.position + cameraTransform.forward * 10f;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ray ray = Camera.main.ScreenPointToRay(inputHandler.GetMousePosition());
|
|
||||||
targetPosition = Physics.Raycast(ray, out RaycastHit hit)
|
|
||||||
? hit.point
|
|
||||||
: cameraTransform.position + cameraTransform.forward * 10f;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PerformOrbitRotation(Transform cameraTransform)
|
|
||||||
{
|
|
||||||
Vector2 orbitDelta = inputHandler.GetLookDelta();
|
Vector2 orbitDelta = inputHandler.GetLookDelta();
|
||||||
if (orbitDelta.sqrMagnitude < float.Epsilon) return;
|
if (orbitDelta.sqrMagnitude < float.Epsilon) return;
|
||||||
|
|
||||||
Vector3 directionToTarget = targetPosition - cameraTransform.position;
|
Transform cameraTransform = virtualCamera.transform;
|
||||||
float distance = directionToTarget.magnitude;
|
|
||||||
|
|
||||||
// 수평 회전
|
// 현재 회전값을 오일러 각도로 가져오기
|
||||||
cameraTransform.RotateAround(targetPosition, Vector3.up, orbitDelta.x * orbitSpeed);
|
Vector3 currentEuler = cameraTransform.eulerAngles;
|
||||||
|
|
||||||
// 수직 회전 제한 추가
|
// X축 회전값을 -80도에서 80도 사이로 제한하기 위해 360도 형식에서 변환
|
||||||
Vector3 right = Vector3.Cross(Vector3.up, directionToTarget.normalized);
|
float currentX = currentEuler.x;
|
||||||
float currentAngle = Vector3.Angle(Vector3.up, directionToTarget);
|
if (currentX > 180f) currentX -= 360f;
|
||||||
float newAngle = currentAngle - orbitDelta.y * orbitSpeed;
|
|
||||||
|
|
||||||
if (newAngle > 5f && newAngle < 175f)
|
// 새로운 회전값 계산
|
||||||
{
|
float newX = currentX - orbitDelta.y * orbitSpeed;
|
||||||
cameraTransform.RotateAround(targetPosition, right, -orbitDelta.y * orbitSpeed);
|
float newY = currentEuler.y + orbitDelta.x * orbitSpeed;
|
||||||
|
|
||||||
|
// X축 회전 제한 (-80도 ~ 80도)
|
||||||
|
newX = Mathf.Clamp(newX, -80f, 80f);
|
||||||
|
|
||||||
|
// 회전 적용
|
||||||
|
Quaternion targetRotation = Quaternion.Euler(newX, newY, 0f);
|
||||||
|
cameraTransform.rotation = targetRotation;
|
||||||
|
|
||||||
|
// 원점으로부터의 거리 유지
|
||||||
|
float distance = cameraTransform.position.magnitude;
|
||||||
|
|
||||||
|
// 새로운 위치 계산 (원점으로부터의 거리 유지)
|
||||||
|
Vector3 newPosition = targetRotation * Vector3.back * distance;
|
||||||
|
cameraTransform.position = newPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 거리 유지
|
private void RestoreInitialCameraState()
|
||||||
cameraTransform.position = targetPosition - cameraTransform.forward * distance;
|
{
|
||||||
|
if (!isInitialStateSet || currentCamera == null) return;
|
||||||
|
|
||||||
|
currentCamera.transform.position = initialPosition;
|
||||||
|
currentCamera.transform.rotation = initialRotation;
|
||||||
|
|
||||||
|
// 회전 중심점 초기화
|
||||||
|
rotationCenter = new Vector3(0f, initialPosition.y, 0f);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Camera Management
|
#region Camera Management
|
||||||
public void SwitchToCamera(int index)
|
public void Set(int index)
|
||||||
{
|
{
|
||||||
if (!IsValidCameraIndex(index)) return;
|
if (cameraPresets == null || index < 0 || index >= cameraPresets.Count) return;
|
||||||
|
|
||||||
var newPreset = cameraPresets[index];
|
var newPreset = cameraPresets[index];
|
||||||
if (!newPreset.IsValid())
|
if (!newPreset.IsValid()) return;
|
||||||
{
|
|
||||||
Debug.LogWarning($"프리셋 {index}의 카메라가 설정되지 않았습니다.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var oldPreset = currentPreset;
|
var oldPreset = currentPreset;
|
||||||
currentPreset = newPreset;
|
currentPreset = newPreset;
|
||||||
UpdateCameraPriorities(newPreset.virtualCamera);
|
UpdateCameraPriorities(newPreset.virtualCamera);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnCameraChanged?.Invoke(oldPreset, newPreset);
|
OnCameraChanged?.Invoke(oldPreset, newPreset);
|
||||||
}
|
}
|
||||||
catch (System.Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError($"카메라 변경 이벤트 처리 중 오류 발생: {e.Message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug.Log($"카메라 전환: {newPreset.presetName}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsValidCameraIndex(int index) =>
|
|
||||||
cameraPresets != null && index >= 0 && index < cameraPresets.Count;
|
|
||||||
|
|
||||||
private void UpdateCameraPriorities(CinemachineCamera newCamera)
|
private void UpdateCameraPriorities(CinemachineCamera newCamera)
|
||||||
{
|
{
|
||||||
if (newCamera == null)
|
if (newCamera == null) return;
|
||||||
{
|
|
||||||
Debug.LogError("새로운 카메라가 null입니다.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentCamera != null)
|
if (currentCamera != null)
|
||||||
{
|
{
|
||||||
@ -492,16 +480,11 @@ public class CameraManager : MonoBehaviour
|
|||||||
#region Hotkey Management
|
#region Hotkey Management
|
||||||
public void StartRecordingHotkey(int presetIndex)
|
public void StartRecordingHotkey(int presetIndex)
|
||||||
{
|
{
|
||||||
if (!IsValidCameraIndex(presetIndex)) return;
|
if (cameraPresets == null || presetIndex < 0 || presetIndex >= cameraPresets.Count) return;
|
||||||
|
|
||||||
var preset = cameraPresets[presetIndex];
|
var preset = cameraPresets[presetIndex];
|
||||||
if (!preset.IsValid())
|
if (!preset.IsValid()) return;
|
||||||
{
|
|
||||||
Debug.LogWarning($"프리셋 {presetIndex}가 유효하지 않습니다.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 다른 프리셋의 레코딩 중지
|
|
||||||
foreach (var otherPreset in cameraPresets)
|
foreach (var otherPreset in cameraPresets)
|
||||||
{
|
{
|
||||||
if (otherPreset?.hotkey?.isRecording == true)
|
if (otherPreset?.hotkey?.isRecording == true)
|
||||||
@ -515,7 +498,7 @@ public class CameraManager : MonoBehaviour
|
|||||||
|
|
||||||
public void StopRecordingHotkey(int presetIndex)
|
public void StopRecordingHotkey(int presetIndex)
|
||||||
{
|
{
|
||||||
if (!IsValidCameraIndex(presetIndex)) return;
|
if (cameraPresets == null || presetIndex < 0 || presetIndex >= cameraPresets.Count) return;
|
||||||
|
|
||||||
var preset = cameraPresets[presetIndex];
|
var preset = cameraPresets[presetIndex];
|
||||||
if (preset?.hotkey?.isRecording == true)
|
if (preset?.hotkey?.isRecording == true)
|
||||||
|
|||||||
@ -0,0 +1,6 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public interface IController
|
||||||
|
{
|
||||||
|
void Set(int index);
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8ce235b59de5fa1479db9cbff684d71a
|
||||||
@ -1,63 +1,47 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.InputSystem;
|
|
||||||
|
|
||||||
public class InputHandler : MonoBehaviour
|
public class InputHandler : MonoBehaviour
|
||||||
{
|
{
|
||||||
private Vector2 lookDelta;
|
private Vector2 lastMousePosition;
|
||||||
private float zoomDelta;
|
private float lastScrollValue;
|
||||||
private Vector2 mousePosition;
|
|
||||||
private bool isRightMouseHeld;
|
private bool isRightMouseHeld;
|
||||||
private bool isMiddleMouseHeld;
|
private bool isMiddleMouseHeld;
|
||||||
private bool isLeftMouseHeld;
|
private bool isOrbitActive;
|
||||||
private bool isAltHeld;
|
private bool isZoomActive;
|
||||||
private bool wasOrbitActiveLastFrame;
|
|
||||||
|
|
||||||
public void OnLook(InputValue value)
|
private void Update()
|
||||||
{
|
{
|
||||||
lookDelta = value.Get<Vector2>();
|
// 마우스 버튼 상태 업데이트
|
||||||
|
isRightMouseHeld = Input.GetMouseButton(1);
|
||||||
|
isMiddleMouseHeld = Input.GetMouseButton(2);
|
||||||
|
isOrbitActive = Input.GetKey(KeyCode.LeftAlt) && Input.GetMouseButton(0); // Alt + 좌클릭으로 궤도 회전
|
||||||
|
isZoomActive = Input.GetKey(KeyCode.LeftControl) && Input.GetMouseButton(0); // Ctrl + 좌클릭으로 줌
|
||||||
|
|
||||||
|
// 마우스 위치 업데이트
|
||||||
|
lastMousePosition = Input.mousePosition;
|
||||||
|
lastScrollValue = Input.mouseScrollDelta.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnZoom(InputValue value)
|
|
||||||
{
|
|
||||||
zoomDelta = value.Get<float>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMousePosition(InputValue value)
|
|
||||||
{
|
|
||||||
mousePosition = value.Get<Vector2>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnRightMouse(InputValue value)
|
|
||||||
{
|
|
||||||
isRightMouseHeld = value.isPressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMiddleMouse(InputValue value)
|
|
||||||
{
|
|
||||||
isMiddleMouseHeld = value.isPressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnLeftMouse(InputValue value)
|
|
||||||
{
|
|
||||||
isLeftMouseHeld = value.isPressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnAlt(InputValue value)
|
|
||||||
{
|
|
||||||
isAltHeld = value.isPressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2 GetLookDelta() => lookDelta;
|
|
||||||
public float GetZoomDelta() => zoomDelta;
|
|
||||||
public Vector2 GetMousePosition() => mousePosition;
|
|
||||||
public bool IsRightMouseHeld() => isRightMouseHeld;
|
public bool IsRightMouseHeld() => isRightMouseHeld;
|
||||||
public bool IsMiddleMouseHeld() => isMiddleMouseHeld;
|
public bool IsMiddleMouseHeld() => isMiddleMouseHeld;
|
||||||
public bool IsOrbitActive() => isAltHeld && isLeftMouseHeld;
|
public bool IsOrbitActive() => isOrbitActive;
|
||||||
public bool IsOrbitStarting()
|
public bool IsZoomActive() => isZoomActive;
|
||||||
|
|
||||||
|
public Vector2 GetLookDelta()
|
||||||
{
|
{
|
||||||
bool isOrbitActive = IsOrbitActive();
|
return new Vector2(
|
||||||
bool isStarting = isOrbitActive && !wasOrbitActiveLastFrame;
|
Input.GetAxis("Mouse X"),
|
||||||
wasOrbitActiveLastFrame = isOrbitActive;
|
Input.GetAxis("Mouse Y")
|
||||||
return isStarting;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float GetZoomDelta()
|
||||||
|
{
|
||||||
|
return Input.mouseScrollDelta.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 GetMousePosition()
|
||||||
|
{
|
||||||
|
return Input.mousePosition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user