Unity

Unity 3D TPS 카메라 컨트롤러 구현

우대비 2025. 3. 5. 16:19
반응형

게임 개발에서 카메라 컨트롤은 플레이어 경험을 좌우하는 중요한 요소입니다.

이번 포스트에서는 캐릭터를 중심으로 회전하는 3D 카메라 컨트롤러를 Unity에서 구현하는 방법을 소개하겠습니다.


🎯 목표

  • 마우스를 이용한 카메라 회전
  • 마우스 휠을 이용한 줌 기능
  • 카메라와 캐릭터 사이 충돌 감지

 

🛠️ 멤버 변수 및 역할

[SerializeField] Transform target; // 카메라가 따라갈 대상 (캐릭터)
[SerializeField] private float minDistance = 1f; // 카메라 최소 거리
[SerializeField] private float maxDistance = 5f; // 카메라 최대 거리
[SerializeField] private float cameraDist = 3f; // 현재 카메라 거리 & 초기 거리

public float sensitivity = 100f; // 마우스 감도
public float minXRot = -50f; // 카메라의 최소 X축 회전값
public float maxXRot = 50f; // 카메라의 최대 X축 회전값

private float rotationX = 0f; // 현재 X축 회전값
private Vector2 mouseDir; // 현재 마우스 입력값 저장
private Vector3 cameraDir; // 플레이어 -> 카메라 방향

 

 

🎮 입력 처리

 // 🎮 마우스 입력을 받아 카메라 회전에 반영
void MouseInput(InputAction.CallbackContext context)
{
    if (context.phase == InputActionPhase.Canceled)
    {
        mouseDir = Vector3.zero;
        return;
    }
    mouseDir = context.ReadValue<Vector2>();
}

// 🔍 마우스 휠 입력을 받아 카메라 줌 조절
void MouseWheelInput(InputAction.CallbackContext context)
{
    float y = context.ReadValue<Vector2>().y;
    cameraDist += Mathf.Clamp(-y, -1f, 1f);
    cameraDist = Mathf.Clamp(cameraDist, minDistance, maxDistance);
}

 

  • 카메라 회전, 충돌 감지 함수에서 사용될 변수에 값을 넣어줍니다.
  • 마우스 휠 입력을 감지하여 카메라의 거리(cameraDist)를 조절합니다.
  • Mathf.Clamp()를 사용하여 너무 멀거나 가까워지는 것을 방지합니다.

 

🎥 카메라 회전

void MoveCamera()
{
    transform.position = target.position;
    Vector2 mouseDelta = mouseDir * sensitivity * Time.deltaTime;

    transform.Rotate(Vector3.up * mouseDelta.x);
    rotationX -= mouseDelta.y;
    rotationX = Mathf.Clamp(rotationX, minXRot, maxXRot);
    transform.localRotation = Quaternion.Euler(rotationX, transform.localEulerAngles.y, 0f);

    mouseDir = Vector2.zero;
}
  • 마우스 입력을 받아 캐릭터 주변을 회전하도록 처리합니다.
  • rotationX 값을 제한하여 카메라가 위아래로 뒤집히지 않도록 합니다.

 

 

🛑 카메라와 캐릭터 사이 충돌 감지 후 거리 조절

void SetCameraDist()
{
    float dist = cameraDist;
    Vector3 dir = (Camera.main.transform.position - transform.position).normalized;
    Ray ray = new Ray(transform.position + Vector3.up * 0.2f, dir);

    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, cameraDist))
        dist = (hit.point - transform.position).magnitude;

    Camera.main.transform.localPosition = cameraDir * dist;
}
  • Physics.Raycast()를 사용하여 카메라와 캐릭터 사이 장애물을 감지합니다.
  • 충돌이 발생하면 카메라가 장애물을 뚫고 지나가지 않도록 거리(cameraDist)를 조정합니다.

 

반응형
LIST