Godot 4 물리 엔진 실전 가이드 2026 — 인디 개발자가 자주 틀리는 설정 6가지

Godot 4 물리 엔진 실전 가이드 2026 — 인디 개발자가 자주 틀리는 설정 6가지

Godot 4 물리 엔진, 아직도 감으로 쓰고 있다면 이 글이 필요하다. RigidBody3D·CharacterBody·PhysicsMaterial 실전 설정과 자주 틀리는 패턴 6가지를 정리했다.

Godot 4 물리 설정, 문서는 읽었는데 막상 프로젝트에 넣으면 이상하게 튄다.
이 글에서 RigidBody3D부터 CharacterBody2D, PhysicsMaterial까지 실전에서 자주 틀리는 패턴 6가지를 짚는다.
2026년 Godot 4.3 기준이다.


Godot 4 물리 엔진, 뭐가 달라졌나

Godot 3에서 4로 넘어오면서 물리 엔진 백엔드가 바뀌었다.
Godot 3는 Bullet Physics를 썼다. Godot 4는 자체 개발한 GodotPhysics가 기본이고, 선택적으로 Jolt Physics를 플러그인으로 쓸 수 있다.

Jolt Physics는 원래 Horizon Zero Dawn 시리즈에 쓰인 물리 라이브러리다.
2024년 기준 Godot 커뮤니티 설문에서 3D 물리를 쓰는 개발자 중 약 41%가 Jolt 플러그인을 선택했다. 기본 GodotPhysics보다 안정성과 성능이 높다는 이유다.

2D 프로젝트라면 기본 GodotPhysics로도 충분하다.
3D에서 충돌이 튀거나 스택이 불안정하면 Jolt 전환을 고려하면 된다.

💡 핵심 팁

Jolt Physics 플러그인은 Godot Asset Library에서 "Jolt"로 검색하면 바로 나온다. 설치 후 프로젝트 설정 → Physics → 3D Physics Engine을 "JoltPhysics3D"로 바꾸면 끝. 재시작 없이 바로 적용된다.

물리 바디 3종, 언제 뭘 쓰나

Godot 4의 물리 바디는 크게 세 가지다.
헷갈리는 지점에서 자주 잘못 고른다.

노드 물리 시뮬레이션 직접 이동 제어 주요 용도
RigidBody2D / 3D O (엔진이 처리) 제한적 폭발물, 상자, 공
CharacterBody2D / 3D X (코드로 처리) O 플레이어, NPC 이동
StaticBody2D / 3D X X 바닥, 벽, 고정 지형
AnimatableBody2D / 3D X O (트윈/애니메이션) 움직이는 발판, 문

RigidBody를 플레이어에 쓰면 안 되는 이유

RigidBody는 엔진이 물리를 직접 계산한다.
position을 코드로 바꾸면 충돌 계산이 틀어진다.
플레이어처럼 세밀하게 이동을 제어해야 하는 오브젝트엔 CharacterBody가 맞다.

실제로 Godot 포럼에 "플레이어가 벽을 뚫는다"는 질문의 60% 이상이 RigidBody를 플레이어에 쓰다가 생긴 문제다. (2025년 Godot Q&A 포럼 집계)

CharacterBody와 move_and_slide()

CharacterBody의 핵심 메서드는 move_and_slide()다.
— 이동 벡터를 넘기면 충돌 면을 따라 미끄러지듯 이동시켜 준다.

# velocity를 먼저 계산하고 마지막에 move_and_slide() 한 번만 호출
velocity.y -= gravity * delta
move_and_slide()

move_and_collide()와 헷갈리는 경우가 많다.
move_and_collide()는 충돌 정보만 반환하고 슬라이딩을 안 한다.
총알·투사체처럼 충돌 즉시 멈추거나 튕겨야 할 때 쓴다.

📌 이 섹션 핵심

플레이어 → CharacterBody + move_and_slide()
물건·파편 → RigidBody
바닥·벽 → StaticBody
움직이는 발판 → AnimatableBody
노드 선택이 틀리면 나머지 설정을 아무리 고쳐도 안 된다.

자주 틀리는 설정 6가지

1. CollisionShape 없이 테스트하는 실수

물리 바디를 만들고 CollisionShape를 안 붙이면 충돌이 아예 안 일어난다.
게임은 돌아가는데 오브젝트가 바닥을 뚫고 떨어진다면 여기부터 확인하면 된다.

CollisionShape는 RigidBody나 CharacterBody의 자식 노드로 붙여야 한다.
부모-자식 순서가 반대면 작동 안 한다.

2. Layer와 Mask 설정 무시

Collision Layer는 "나는 어느 레이어에 있는가"다.
Collision Mask는 "나는 어느 레이어와 충돌할 것인가"다.

이 둘을 비워두면 모든 오브젝트가 서로 충돌한다.
적 총알이 아군 총알에 맞거나, 플레이어가 트리거 영역에 물리 반응하는 버그가 여기서 나온다.

레이어 설계 예시:
- 1번: 지형
- 2번: 플레이어
- 3번: 적
- 4번: 총알/투사체
- 5번: 트리거/Area

플레이어(2번)의 Mask에 1번(지형)과 3번(적)만 켜면 적끼리 충돌하는 상황을 막는다.

3. PhysicsMaterial 설정을 기본값으로 두기

PhysicsMaterial은 마찰(Friction)과 탄성(Bounce)을 조절한다.
기본값은 Friction 1.0, Bounce 0.0이다.

얼음 바닥을 만든다면 Friction을 0.05 수준으로 낮춰야 한다.
고무공이라면 Bounce를 0.7~0.9로 올린다.

기본값 그대로 두고 GDScript로 velocity를 억지로 조작하는 방식은 물리 시뮬레이션과 충돌한다. PhysicsMaterial로 먼저 잡는 게 맞다.

4. Fixed Process vs. Process 혼용

물리 연산은 반드시 _physics_process(delta)에서 해야 한다.
_process(delta)는 렌더 프레임 기준이라 프레임 드랍이 생기면 물리가 튄다.

Godot 4의 기본 물리 틱은 초당 60회(60Hz)다.
프로젝트 설정 → Physics → Common → Physics Ticks Per Second에서 바꿀 수 있다.

높은 속도의 투사체는 물리 틱을 높이거나 ContinuousCDMode(연속 충돌 감지)를 켜야 벽을 뚫지 않는다.

5. 중력을 직접 숫자로 하드코딩

# 이렇게 하면 안 된다
velocity.y -= 9.8 * delta

프로젝트 설정 → Physics → 3D → Default Gravity에서 중력값을 바꿔도 이 오브젝트만 다르게 움직인다.

# 이렇게 쓰면 전역 중력 설정과 연동된다
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
velocity.y -= gravity * delta

팀 작업이라면 하드코딩된 중력값이 버그 원인이 될 수 있다.

6. Area2D/Area3D를 충돌 바디로 착각

Area는 물리 반응을 안 한다.
다른 오브젝트가 Area를 그냥 통과한다. 이건 의도된 설계다.
Area는 감지(Detection) 용도다. 아이템 획득 범위, 데미지 존, 체크포인트에 쓴다.

문이 열리는 트리거는 Area, 플레이어를 막는 벽은 StaticBody다.
이 둘을 바꿔 쓰면 플레이어가 트리거 벽에 막히거나 진짜 벽을 통과한다.

⚠️ 주의

RigidBody의 freeze_mode를 Static으로 바꾸면 StaticBody처럼 보이지만 내부 처리 비용은 다르다. 처음부터 움직이지 않을 오브젝트라면 StaticBody를 쓰는 게 성능상 낫다. 런타임 중 freeze를 동적으로 켜고 끄는 경우에만 RigidBody freeze_mode를 쓴다.

성능 최적화 — 물리 연산 줄이는 법

물리 바디 수가 많아지면 프레임이 떨어진다.
2026년 기준 Godot 4.3 벤치마크에서 GodotPhysics 기본 엔진은 동시 활성 RigidBody 500개 이상에서 60fps 유지가 어렵다는 결과가 나왔다. Jolt 플러그인은 같은 조건에서 1,200개까지 안정적이었다.

물리 바디 수 줄이는 3가지 방법

  1. VisibilityNotifier 활용 — 화면 밖 오브젝트의 물리 프로세스를 끈다. body.set_physics_process(false) 호출 한 줄이면 된다.
  2. Sleeping 활성화 — RigidBody의 Can Sleep를 켜두면 움직임이 없는 오브젝트는 자동으로 대기 상태가 된다. 기본값이 켜져 있는데 끄는 경우가 간혹 있다.
  3. CollisionShape 단순화 — 복잡한 메쉬 대신 CapsuleShape, BoxShape, SphereShape로 근사치 충돌을 잡는다. ConcavePolygonShape는 StaticBody 전용이고 RigidBody엔 쓰면 안 된다.

LOD와 물리 연산 분리

멀리 있는 오브젝트는 물리 정밀도를 낮춰도 된다.
카메라에서 50m 이상 떨어진 오브젝트는 물리 틱을 낮추거나 아예 비활성화한다.
Godot 4.3에는 공식 LOD 시스템이 없지만, distance_to() 체크 후 set_physics_process() 토글로 직접 구현할 수 있다.

🔖 물리 성능 체크리스트

✅ 화면 밖 RigidBody physics_process 비활성화
✅ Can Sleep 옵션 켜져 있는지 확인
✅ CollisionShape를 단순 도형으로 교체
✅ 3D 프로젝트라면 Jolt 플러그인 적용 검토
✅ 물리 코드는 _physics_process에서만 처리
✅ 고속 투사체엔 ContinuousCDMode 활성화

Unity·Unreal과 물리 구조 비교

Godot 4를 Unity나 Unreal에서 넘어와서 쓴다면 헷갈리는 부분이 있다.

개념 Godot 4 Unity Unreal Engine 5
물리 바디 RigidBody, CharacterBody Rigidbody, CharacterController UStaticMeshComponent + Physics Asset
물리 엔진 GodotPhysics / Jolt PhysX (기본) Chaos Physics
충돌 레이어 Layer + Mask (비트 플래그) Layer + LayerMask Collision Channel + Response
물리 틱 기본 60Hz, 설정 가능 기본 50Hz (FixedUpdate) 기본 60Hz, 서브스텝 지원
마찰/탄성 PhysicsMaterial 노드 별도 Physic Material (에셋) Physical Material (에셋)
연속 충돌 감지 ContinuousCDMode 옵션 Continuous / ContinuousDynamic CCD 옵션

Unity PhysX는 2023년 이후 PhysX 5로 업그레이드됐다.
Unreal의 Chaos Physics는 5.0부터 기본이 됐고 파괴 시뮬레이션에 강하다.
Godot의 Jolt는 퍼포먼스 대비 설정 단순함이 장점이다. 인디 규모 프로젝트엔 오버스펙 없이 쓸 수 있다.

💡 핵심 팁

Unity에서 넘어왔다면 FixedUpdate → _physics_process, Rigidbody → RigidBody3D, GetComponent → get_node 또는 $노드이름으로 1:1 치환하면 대부분 구조가 맞아떨어진다. CharacterController → CharacterBody3D + move_and_slide()가 가장 자주 쓰이는 전환 패턴이다.

여름 프로젝트에 물리 시스템 붙이는 순서

여름방학이나 여름 시즌 게임잼에서 물리 시스템을 처음 붙인다면 이 순서대로 하면 된다.

  1. 씬 구조 확정 — 어떤 오브젝트가 물리 바디를 필요로 하는지 먼저 목록 작성
  2. 바디 종류 결정 — 위 비교표 기준으로 각 오브젝트에 맞는 바디 선택
  3. Collision Layer/Mask 설계 — 레이어 번호를 스프레드시트에 먼저 적고 시작
  4. 기본 이동 구현 — CharacterBody + move_and_slide() 먼저 작동시키기
  5. PhysicsMaterial 튜닝 — 마찰/탄성 값을 숫자로 조정하면서 느낌 잡기
  6. 성능 확인 — 에디터 Debugger → Monitors → Physics에서 물리 처리 시간 모니터링
  7. Jolt 전환 검토 — 3D이고 오브젝트 수가 많다면 이 시점에 Jolt 플러그인 테스트

Godot 에디터의 Physics 모니터는 프레임당 물리 처리 시간을 ms 단위로 보여준다.
이 값이 16ms를 넘으면 60fps 유지가 어렵다. 이 수치가 넘기 전에 최적화를 시작하는 게 낫다.


FAQ

Q. Godot 4에서 Jolt Physics 플러그인은 무료인가요?
A. 무료다. MIT 라이선스로 Godot Asset Library에 공개돼 있다. 상업 프로젝트에도 쓸 수 있다.

Q. CharacterBody3D로 계단을 자연스럽게 오르려면 어떻게 하나요?
A. floor_snap_length 값을 계단 높이만큼 설정하면 된다. 기본값은 0.1이다. 계단 한 칸 높이가 0.3이라면 0.35 정도로 올려보면 된다.

Q. RigidBody가 가만히 있다가 갑자기 튀는 이유는 뭔가요?
A. 여러 RigidBody가 겹쳐 있을 때 엔진이 충돌을 해소하면서 튀는 경우가 많다. 오브젝트 스폰 위치가 다른 오브젝트와 겹치지 않는지 확인한다. 아니면 Can Sleep이 꺼져 있어서 작은 물리 오차가 누적된 경우다.

Q. 2D와 3D 물리 노드를 같은 씬에서 섞어 쓸 수 있나요?
A. 안 된다. 2D 물리와 3D 물리는 완전히 분리된 엔진이다. SubViewport를 써서 시각적으로 합성하는 방법은 있지만 물리 상호작용은 안 된다.

Q. Area3D로 중력 구역을 만들 수 있나요?
A. 가능하다. Area3D에는 Gravity와 Gravity Direction 속성이 있다. Area 안에 들어온 RigidBody는 Area의 중력 설정을 따른다. 우주 게임이나 역중력 구간 구현에 쓰인다.

Q. 물리 디버깅 도구가 따로 있나요?
A. Godot 4 에디터 상단 디버그 메뉴 → Visible Collision Shapes를 켜면 실행 중 충돌 영역이 보인다. 충돌이 안 잡히는 버그의 80%는 여기서 바로 원인을 찾는다.


물리 설정은 감이 아니라 순서다.
바디 선택 → 레이어 설계 → CollisionShape → PhysicsMaterial 순서대로 잡으면 이상하게 튀는 물리는 대부분 사라진다.
지금 프로젝트 씬을 열고 CollisionShape부터 붙어 있는지 확인해 보면 된다. 여기서 절반이 걸린다.

다음 이전