본문 바로가기
Game Engine/Unity

(Unity) Spectator Camera - Input System Version

by MeisterTJ 2022. 10. 18.

https://meistertj.tistory.com/10?category=1283237 

 

(Unity) 기본적인 Spectator Camera

Scene 테스트를 할 때 사용하기 유용한 Spectator Camera 코드이다. Main Camera에 추가해서 사용하면 된다. using UnityEngine; public class SpectatorController : MonoBehaviour { [Header("Sensitivity")] p..

meistertj.tistory.com

이전에 Spectator Camera 코드를 올렸었는데, 이는 Input Manager 기반이라 Input System에서는 작동하지 않는다.

 

https://meistertj.tistory.com/27?category=1283237 

 

(Unity) Input System을 이용한 게임패드, 키보드 입력 감지

Steam 게임들을 하다보면 게임패드의 버튼을 누르면 UI가 게임패드 용으로 바뀌고, 다시 키보드를 누르면 UI가 키보드 마우스 용으로 바뀌는 것을 볼 수 있다. 심지어 PS패드, XBOX패드를 각각 따로

meistertj.tistory.com

Input System에 대한 소개는 위 글에서 볼 수 있다.

 

 


Input System을 적용한 Spectator Camera는 기존 Spectator Camera보다는 조금 더 까다롭다.

 

먼저 Input Action 에셋에 Spectator 전용 Action Map을 추가한다.

Input Action 에셋이 없다면 만들면 된다. 

 

그 후 Camera에 Player Input을 추가하고 Input Action Asset을 만든 에셋으로 설정한다. 

 

코드는 다음과 같다.

 

using UnityEngine;
using UnityEngine.InputSystem;

public class FrSpectatorCamera : MonoBehaviour
{
    [Header("Sensitivity")]
    public float sensitivityX = 5f;

    public float sensitivityY = 5f;

    [Header("X Axis Rotation Min, Max")]
    public float minX = -80f;

    public float maxX = 80f;

    [Header("Move Speed")]
    public float moveSpeed = 10f;

    private bool bCursorLocked = false;

    private float rotX;
    private float rotY;

    private float moveSpeedMin = 1f;
    private float moveSpeedMax = 50f;

    // Input 
    private Vector3 moveInput = Vector3.zero;
    private Vector2 mouseLook = Vector2.zero;
    private Vector2 mouseWheel = Vector2.zero;

    void Start()
    {
        // 최초 카메라의 rotation 상태 저장
        rotX = -transform.rotation.eulerAngles.x;
        rotY = transform.rotation.eulerAngles.y;
    }

    private void Update()
    {
        // 매 Update시 Lock 상태 업데이트
        InternalLockUpdate();
    }

    private void LateUpdate()
    {
        if (!bCursorLocked) return;

        // 마우스 좌우 움직임  -> y축 회전
        // 마우스 위아래 움직임 -> x축 회전
        rotY += mouseLook.x * sensitivityX;
        rotX += mouseLook.y * sensitivityY;

        rotX = Mathf.Clamp(rotX, minX, maxX);

        // Mouse Wheel -> Move Speed
        Vector2 wheelDelta = mouseWheel;

        if (wheelDelta.y > 0 || wheelDelta.y < 0)
        {
            moveSpeed = Mathf.Clamp(moveSpeed + wheelDelta.y, moveSpeedMin, moveSpeedMax);
        }

        // Key Input
        float x = moveInput.x;
        float z = moveInput.z;
        float y = moveInput.y;

        var transformRef = transform;
        Vector3 dir = transformRef.right * x + transformRef.up * y + transformRef.forward * z;
        transformRef.rotation = Quaternion.Euler(-rotX, rotY, 0);
        transformRef.position += dir * (moveSpeed * Time.deltaTime);
    }

    private void InternalLockUpdate()
    {
        if (bCursorLocked)
        {
            Cursor.lockState = CursorLockMode.Locked;
            Cursor.visible = false;
        }
        else
        {
            Cursor.lockState = CursorLockMode.None;
            Cursor.visible = true;
        }
    }

    #region Use Input System

    public void OnMove(InputValue _value)
    {
        moveInput = _value.Get<Vector3>();
    }

    public void OnMouseLook(InputValue _value)
    {
        mouseLook = _value.Get<Vector2>();
    }

    public void OnScrollWheel(InputValue _value)
    {
        mouseWheel = _value.Get<Vector2>().normalized;
        Debug.Log(mouseWheel);
    }

#if UNITY_EDITOR
    public void OnClick(InputValue _value)
    {
        bCursorLocked = true;
    }

    public void OnEscape(InputValue _value)
    {
        bCursorLocked = false;
    }
#endif

    #endregion
}