Unity/캐릭터

캐릭터 이동 구현 (Character Controller)

sungmin08 2025. 3. 19. 00:49

1. 컴포넌트 세팅

본 프로젝트에서는 Capsule Object를 사용하여 진행하였으므로 Capsule Collider를 사용하였다.

 

Slope Limit (기울기 제한) 캐릭터가 올라갈 수 있는 최대 경사각을 설정
- 45로 설정하면 45도 이상의 경사면은 올라가지 못함.
Step Offset (계단 높이 보정) 해당 값 이하의 높이를 자동으로 넘을 수 있도록 설정 
- 플레이어가 자잘한 장애물에 걸리지 않게 해줌.
Skin Width (스킨 두께) 콜라이더 표면에서 충돌을 감지하는 버퍼 거리
- 너무 작은 값이면 벽에 박거나 충돌 버그 발생 / 너무 크면 충돌이 이상하게 감지될 수 있음.
Min Move Distance (최소 이동 거리) 레이어가 최소한으로 움직여야 적용되는 거리
- 너무 작으면 이동 감지가 너무 자주 발생하여 성능에 영향
Center (중심 위치) Character Controller의 중심 위치를 설정
- 플레이어 모델이 정중앙이 아닐 경우 중심을 맞출 때 사용.
- 플레이어의 실제 발바닥에 맞추려면 Y = 1 등으로 조정 가능.
Radius (반지름) Character Controller의 가로 크기 (반지름).
Height (높이) Character Controller의 전체 높이.

2. Player Controller 코드 작성

using UnityEngine;
using UnityEngine.EventSystems;

public class PlayerController : MonoBehaviour
{
    [SerializeField] private float speed = 3.0f;
    [SerializeField] private float mouseSensitivity = 2.0f;
    private float verticalRotation = 0;
    private Vector3 moveDirection = Vector3.zero;
    
    [Header("Component")]
    private CharacterController characterController;
    private Camera playerCamera;

    private void Start()
    {
        characterController = GetComponent<CharacterController>();
        playerCamera = GetComponentInChildren<Camera>();
        Cursor.lockState=CursorLockMode.Locked;
    }

    private void Update()
    {
        float vertical = Input.GetAxis("Vertical");
        float horizontal = Input.GetAxis("Horizontal");
        Vector3 move = transform.right * horizontal + transform.forward * vertical;
        moveDirection = move * speed;
        characterController.Move(moveDirection * Time.deltaTime);

        //RigidBody 방식(characterController 컴포넌트 사용후 이 코드 작성 시 물리적인 충돌이 발생하지 않음)
        //transform.Translate(Vector3.forward * Time.deltaTime * speed * vertical);
        //transform.Translate(Vector3.right * Time.deltaTime * speed * horizontal);


        float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
        float mouseY = Input.GetAxis("Mouse Y") * (mouseSensitivity * (Screen.width / (float)Screen.height));
        transform.Rotate(Vector3.up * mouseX);
        verticalRotation -= mouseY;
        verticalRotation = Mathf.Clamp(verticalRotation, -60, 60);
        playerCamera.transform.localRotation = Quaternion.Euler(verticalRotation, 0, 0);
    }
}

 

알아야 할 코드

//게임을 진행하는 동안 마우스 커서를 게임씬 내로 한정함
Cursor lockState=CursorLockMode.Locked
//플레이어 카메라 회전의 수평수직 감도가 같도록 하기 위해서 모니터 해상도 비율에 맞게 Y축 감도가 보정됨.
float mouseY = Input.GetAxis("Mouse Y") * (mouseSensitivity * (Screen.width / (float)Screen.height));

보정 안할 시 Y축 감도는 X축보다 현저히 낮아짐.