[Unity] Character Controller (캐릭터 컨트롤러)

⭐ Character Controller

유니티에 내장되어 있는 패키지로 캐릭터 움직임을 구현할 수 있는 컴포넌트입니다.

캡슐 형태의 충돌 범위가 포함되어 있으며 Rigidbody 물리를 활용하지 않는

3인 또는 1인 플레이어 컨트롤러에 주로 사용됩니다.

 

하지만 캐릭터가 지면에 닿아있는지 체크하는 isGrounded 프로퍼티가 정확한 값을 체크하지 못하는 등의

다양한 잔버그가 있기 때문에 정교한 물리를 이용한 캐릭터 컨트롤러를 만들땐 직접 구현하는 것을 추천합니다.

 

 

 

주요 속성 (Properties)


Character Controller 컴포넌트

 

속성 설명
Slope Limit 이동할 수 있는 최대 경사 각도 (기본값 45도)
Step Offset 캐릭터가 자동으로 오를 수 있는 최대 계단 높이
Skin Width 충돌 감지를 위한 여유 거리 (값이 작을수록 더 정확한 충돌 감지)
Min Move Distance 너무 작은 이동값은 무시되도록 하는 최소 이동 거리
Center 캡슐 충돌체의 중심 위치 (로컬 좌표)
Radius 충돌체의 반지름
Height 충돌체의 높이
isGrounded 캐릭터가 현재 지면에 닿아 있는지 여부
velocity 마지막 Move() 호출에서 계산된 이동 속도 (읽기 전용)
detectCollision 충돌 감지 여부 (false일 경우 충돌 무시)

 

 

 

 

주요 함수 (Methods)


함수 설명
Move(Vector3 motion) 지정된 방향과 거리로 이동 (물리 시간과 상관없이 매 프레임 호출)
SimpleMove(Vector3 speed) 속도를 받아 중력 자동 적용 + 이동 (물리 시간 기반)
enabled 컨트롤러 활성화/비활성화 제어

 

 

 

 

Character Controller의 장단점


💡 장점

● 움직임을 구현하기 간단합니다.

● 물리 엔진 영향 없이 충돌만 처리 가능합니다.

● 계단 오르기, 경사 체크 등을 편하게 처리할 수 있습니다.

 

💡 단점

● 물리 기반의 상호작용에 제한이 있습니다.

● 정교한 움직임을 구현하기에 한계가 있습니다.

● 기존의 캐릭터 컨트롤러를 수정하거나 확장하기 어렵습니다.

● 바닥 체크 판정이 불안정합니다. → 정확한 판정이 안될 때가 있음

 

 

 

 

Character Controller 예제


캐릭터 컨트롤러를 이용해 간단한 이동과 점프를 구현한 예제 코드입니다.

● W, A, S, D 키를 이용해 이동 구현

● 스페이스바 키를 이용해 점프 구현

 

using UnityEngine;
using UnityEngine.InputSystem;

public class Player_CharacterController : MonoBehaviour
{
    public float speed = 5f;
    public float jumpHeight = 5f;
    public float gravity = 9.81f;

    private CharacterController controller;
    private Vector3 moveInput;

    private InputAction moveAction;
    private InputAction jumpAction;

    private void Awake()
    {
        controller = GetComponent<CharacterController>();
        moveAction = InputSystem.actions["Move"];
        jumpAction = InputSystem.actions["Jump"];
    }

    private void FixedUpdate()
    {
        //중력 적용
        moveInput.y -= gravity * Time.fixedDeltaTime;

        //이동 함수
        controller.Move(speed * Time.fixedDeltaTime * moveInput);
    }

    public void Move(InputAction.CallbackContext context)
    {
        //W,A,S,D 눌렀을 때 moveInput 벡터 값에 넣어줌
        Vector2 moveDir = context.ReadValue<Vector2>();
        moveInput = new Vector3(moveDir.x, moveInput.y, moveDir.y);
    }

    //W,A,S,D 키를 뗐을 때 moveInput을 0, 0, 0으로 만들어줌
    public void MoveCancel(InputAction.CallbackContext context) => moveInput = Vector3.zero;

    public void Jump(InputAction.CallbackContext context)
    {
        if(context.started)
        {
            //캐릭터가 지면에 닿아있으면
            if (controller.isGrounded)
            {
                //점프
                moveInput.y = jumpHeight;
            }
        }
    }

    private void OnEnable()
    {
        //인풋시스템 이벤트 등록
        moveAction.performed += Move;
        moveAction.canceled += MoveCancel;
        jumpAction.started += Jump;
    }

    private void OnDisable()
    {
        //인풋시스템 이벤트 해제
        moveAction.performed -= Move;
        moveAction.canceled -= MoveCancel;
        jumpAction.started -= Jump;
    }
}

 

'개발, IT > 유니티' 카테고리의 다른 글

[Unity] 유니티 포톤 PUN  (0) 2026.01.09
[Unity] 게임 네트워크  (0) 2026.01.06
[Unity] Light (빛, 광원)  (0) 2025.11.16
[Unity] Particle System (파티클 시스템)  (0) 2025.11.16
[Unity] Audio (오디오) / 소리 재생하기  (0) 2025.11.16