물리 기반 조정 (중력, 충돌)
전역·액터 중력을 조정하고 Block·Overlap·Ignore 충돌 응답과 고속 이동의 연속 충돌 검사를 설정합니다.
중력과 충돌은 물리 시스템에서 플레이어가 가장 먼저 느끼는 설정입니다. 값 하나만 어긋나도 캐릭터가 둥둥 떠다니거나, 물체가 벽을 뚫고 지나가거나, 총알이 맞아야 할 곳을 그냥 통과합니다. 이런 문제는 숫자를 이리저리 바꿔서는 잘 고쳐지지 않고, 어떤 물체가 어떤 규칙을 따르는지부터 구분해야 풀립니다.
이 글에서는 중력을 프로젝트 전체와 액터마다 조정하는 방법을 먼저 보고, 충돌에서 두 물체의 응답이 어떻게 합쳐지는지 그림으로 정리합니다. 그다음 충돌 프리셋과 커스텀 채널, 단순 충돌과 복잡 충돌, Hit와 Overlap 이벤트를 차례로 다룬 뒤, 중력과 겹침을 직접 확인하는 실습을 합니다. 이 글을 마치면 물리 반응을 감이 아니라 기준으로 조정할 수 있습니다.
중력 조정하기
중력은 모든 물리 시뮬레이션의 바탕으로, 물체가 아래로 떨어지게 만듭니다. 언리얼 엔진은 프로젝트 전체에 적용되는 기본 중력과, 액터마다 중력을 켜고 끄는 설정을 따로 둡니다.
프로젝트의 기본 중력
프로젝트의 기본 중력은 Edit 메뉴의 Project Settings에서 Engine의 Physics에 있는 Default Gravity Z로 정합니다. 기본값은 -980.0 cm/s²로, 지구의 표준 중력과 거의 같습니다.
이 값의 절댓값을 줄여 -100.0처럼 만들면 물체가 더 천천히 떨어져 달이나 우주 같은 느낌이 납니다. 같은 처음 속도로 점프한다면 더 높이 올라가고 더 오래 떠 있게 됩니다. 반대로 절댓값을 키워 -2000.0처럼 만들면 물체가 더 빨리 떨어져 중력이 강한 행성처럼 느껴지고, 같은 처음 속도의 점프는 더 낮고 짧아집니다. 게임 전체의 분위기를 정할 때 씁니다. 저중력 행성처럼 특정 레벨에만 다른 중력을 주려면 프로젝트 설정을 바꾸지 말고, 그 레벨의 World Settings에서 Physics 항목의 Override World Gravity를 켜고 Global Gravity Z에 그 레벨의 중력을 적습니다.
액터마다 중력 끄기
물리 시뮬레이션을 켠 스태틱 메시 액터나 스켈레탈 메시 액터는 디테일 패널의 Physics 항목에서 Enable Gravity를 끌 수 있습니다. 그러면 그 액터는 물리 시뮬레이션을 켠 채로 중력의 영향만 받지 않습니다. 우주선이나 무중력 상태의 물체, 플레이어가 직접 움직이는 발판에 씁니다.
여기서 흔한 오해가 있습니다. 중력을 끈다고 그 액터가 지금 위치에 멈춰 고정되지는 않습니다. 이미 가지고 있던 속도와 감쇠, 충돌, 외부에서 받는 힘은 계속 적용되므로, 움직이던 물체는 중력 없이 계속 움직입니다.
중력의 배율도 알아 둡니다. 일반 메시 강체의 Physics 항목에는 모든 물체에 공통으로 쓰는 중력 배율(Gravity Scale) 속성이 없습니다. 캐릭터는 캐릭터 무브먼트 컴포넌트(Character Movement)의 Gravity Scale로 중력의 배율을 정하고, 강체마다 다른 중력 배율이 필요하다면 따로 힘을 가하는 방식으로 직접 만들어야 합니다.
두 물체의 충돌 응답 합치기
충돌은 물체끼리 물리적으로 부딪히는 방식을 정하며, 게임 플레이의 정확성과 사실감에 직접 영향을 줍니다. 충돌을 이해하는 가장 중요한 원리는, 결과가 한쪽의 설정만으로 정해지지 않는다는 점입니다. 두 컴포넌트가 각자 상대의 오브젝트 타입(Object Type)에 대해 정한 응답을 함께 봐야 합니다.
COLLISION · PAIR RESPONSE
차단은 양쪽 모두 Block일 때 성립합니다
충돌 활성화를 전제로, 두 컴포넌트가 상대 Object Type에 정한 응답을 함께 읽습니다. 어느 한쪽이 Ignore이면 이 쌍의 충돌·겹침을 무시합니다.
| 한쪽 응답 | 상대 응답 | 기본 결과 |
|---|---|---|
| Ignore | 어떤 응답이든 | 이 쌍의 충돌·겹침을 무시 |
| Overlap | Overlap 또는 Block | 차단하지 않고 겹침 감지 |
| Block | Block | 이동을 차단 |
- Ignore + 어떤 응답이든
- 이 쌍의 충돌·겹침을 무시
- Overlap + Overlap 또는 Block
- 차단하지 않고 겹침 감지
- Block + Block
- 이동을 차단
Overlap 알림
양쪽 Generate Overlap Events, query 충돌과 채널 응답을 함께 확인합니다.
Hit 알림
Blocking 접촉과 알림은 별개입니다. 시뮬레이션·sweep 이동 방식과 해당 이벤트 설정을 확인합니다.
위 그림은 충돌이 켜져 있다는 전제에서, 한쪽의 응답과 상대의 응답에 따라 어떤 결과가 나오는지 표로 보여 줍니다. 어느 한쪽이라도 Ignore로 응답하면, 상대가 무엇으로 응답하든 이 두 물체는 서로를 무시합니다. 한쪽이 Overlap이고 상대가 Overlap이나 Block이면, 막지는 않고 겹치는 것만 감지합니다. 두 물체가 모두 Block으로 응답할 때에만 서로의 이동을 막습니다. 그림의 제목처럼 차단은 양쪽이 모두 Block일 때만 성립합니다.
그림 아래의 두 카드는 결과와 알림을 구분합니다. 겹침을 감지했다고 Overlap 이벤트가 저절로 오는 것은 아니어서, 양쪽의 Generate Overlap Events와 충돌 검사(query) 설정, 채널 응답을 함께 맞춰야 알림이 생깁니다. 막히는 충돌이 일어나는 것과 Hit 알림을 받는 것도 별개라서, 시뮬레이션인지 경로를 훑는(sweep) 이동인지와 그에 맞는 이벤트 설정을 확인해야 합니다.
충돌 프리셋
충돌 프리셋(Collision Presets)은 물체가 다른 물체와 어떻게 상호작용할지를 미리 정해 둔 규칙 묶음입니다. 스태틱 메시 액터나 구 충돌(Sphere Collision), 상자 충돌(Box Collision) 같은 컴포넌트의 디테일 패널에서 Collision 항목에 있습니다.
| 프리셋 | 하는 일과 쓰는 곳 |
|---|---|
NoCollision | 어떤 물체와도 충돌하지 않고 뚫고 지나갑니다. 배경 장식이나 시각 효과용 메시에 씁니다. |
BlockAll | 기본 채널에 Block으로 응답합니다. 상대의 응답과 Collision Enabled도 맞아야 실제로 막힙니다. 벽, 바닥, 단단한 지형에 씁니다. |
OverlapAll | 기본 채널에 Overlap으로 응답합니다. 양쪽의 이벤트 생성 조건을 맞춰야 알림이 옵니다. 트리거 볼륨이나 상호작용 영역에 씁니다. |
PhysicsActor | 물리 시뮬레이션을 켠 물체에 알맞으며, 플레이어와 움직이는 물체 같은 대부분의 요소를 막습니다. |
Pawn | 플레이어 캐릭터 같은 Pawn에 알맞습니다. |
CharacterMesh | 캐릭터의 몸인 스켈레탈 메시에 알맞습니다. |
대부분의 경우에는 이렇게 미리 정의된 프리셋으로 충분합니다.
커스텀 충돌 설정
특정 종류의 물체하고만 부딪히거나, 특정 종류하고만 겹침 이벤트를 만들고 싶을 때는 Collision Presets에서 Custom...을 골라 직접 정합니다. 커스텀 설정은 두 부분으로 이루어집니다. Object Type은 이 물체가 어떤 종류인지를 정하며, WorldStatic, WorldDynamic, Pawn, PhysicsBody 같은 값이 있습니다. 그리고 다른 오브젝트 타입마다 이 물체가 어떻게 응답할지를 정합니다.
응답에는 세 가지가 있습니다. Ignore는 충돌하지 않고 뚫고 지나가는 것입니다. Overlap은 막지 않고 겹침 감지에 참여하는 것이고, 이벤트를 만들지는 따로 정합니다. Block은 상대도 Block이라면 이동을 막는 것이고, Hit 알림은 시뮬레이션이나 이동 방식과 이벤트 설정에 따라 정해집니다.
예를 들어 총알이라면 Object Type을 Projectile로 정하고, Pawn과 WorldStatic, PhysicsBody에는 Block으로, 아이템인 Pickup에는 Overlap으로 응답하게 할 수 있습니다. 유령 캐릭터라면 Object Type을 Ghost로 정하고 모든 오브젝트 타입에 Overlap으로 응답하게 해서, 물리적으로는 뚫고 지나가지만 겹침 이벤트로 상호작용은 하게 만들 수 있습니다. 여기서 Projectile, Pickup, Ghost는 엔진에 원래 있는 타입이 아니라, 이 예를 위해 Project Settings의 Collision에서 Object Channel로 새로 추가할 이름입니다.
커스텀 채널을 설계할 때는 오브젝트 타입마다의 응답과 이벤트 설정을 함께 정해 두면, 레벨마다 충돌 규칙이 어긋나는 문제를 줄일 수 있습니다.
단순 충돌과 복잡 충돌
충돌을 계산할 때 쓰는 형상도 정해야 합니다. 단순 충돌(Simple Collision)은 물체의 겉모습을 상자, 구, 캡슐, 볼록 껍질(Convex Hull) 같은 단순한 형태로 바꿔 충돌을 계산합니다. 계산이 매우 효율적이라 대부분의 게임 오브젝트에 씁니다. 스태틱 메시 에디터의 툴바에 있는 Collision 메뉴에서 상자나 구, 캡슐 모양의 단순 충돌을 더하거나, Auto Convex Collision으로 볼록 껍질 충돌을 자동으로 만들 수 있습니다.
복잡 충돌(Complex Collision)은 메시의 실제 폴리곤을 그대로 써서 충돌을 계산합니다. 매우 정확하지만 비용이 큽니다. 스태틱 메시 에디터의 디테일 패널에서 Collision 항목의 Collision Complexity로 정합니다. 기본값인 Project Default는 프로젝트의 물리 설정을 따르며, 기본 상태에서는 Simple And Complex처럼 단순 충돌을 요청하는 검사와 복잡 충돌을 요청하는 검사를 따로 처리합니다. Use Complex as Simple은 단순 충돌을 요청하는 검사까지 폴리곤 메시로 처리하는 선택이며, 이렇게 하면 그 메시는 물리 시뮬레이션을 할 수 없습니다.
복잡 충돌은 복잡한 지형의 좁은 통로나, 총알이 정확히 구멍을 지나가야 하는 경우처럼 아주 정밀한 충돌이 필요한 곳에만 제한적으로 씁니다. 캐릭터 자신은 캡슐로 이동하지만, 캐릭터가 부딪힐 정적인 환경에 복잡 충돌을 쓸지는 필요한 형상의 정확도와 비용을 보고 정합니다.
Hit 이벤트와 Overlap 이벤트
막히는 충돌을 알림으로 받으려면 Simulation Generates Hit Events를 씁니다. 물리 시뮬레이션 중의 접촉을 Hit로 받을 컴포넌트에서 이 설정을 켜면 OnComponentHit가 생깁니다. 막히는 접촉 자체와 그 알림은 다른 것이라는 점을 구분하고, 캐릭터 이동이나 경로를 훑는 이동에서도 OnComponentHit가 생길 수 있다는 점을 알아 둡니다. 총알이 벽에 맞았을 때, 상자가 바닥에 떨어졌을 때, 차가 다른 차와 부딪혔을 때 이 이벤트를 씁니다.
겹침을 알림으로 받으려면 양쪽 컴포넌트의 Generate Overlap Events와 충돌 검사(query) 설정, 채널 응답을 함께 맞춥니다. 그러면 실제로 겹치기 시작할 때와 끝날 때 OnComponentBeginOverlap과 OnComponentEndOverlap을 받습니다. 플레이어가 트리거 영역에 들어왔을 때, 아이템을 주웠을 때, 특정 지역에 들어서면 소리를 낼 때 씁니다.
중력과 겹침 확인해 보기
중력 실습은 떨어질 큐브와 그것을 막을 바닥만 있으면 시작할 수 있습니다. 반면 겹침 실습은 조종할 캐릭터와 이동 입력이 준비된 시험 레벨이 필요합니다. 1장의 Blank 프로젝트에 아직 캐릭터를 준비하지 않았다면, 같은 엔진 버전의 Third Person 템플릿으로 시험용 프로젝트를 따로 만들거나 물리 기반 캐릭터 제어의 사전 준비 조건을 먼저 확인합니다. 에디터에서 자유 카메라로 날아다니는 것과, Pawn을 조종해 겹침을 만드는 것은 다른 일이기 때문입니다.
중력 바꿔 보기
File 메뉴의 New Level에서 Basic으로 레벨을 만든 뒤, Project Settings의 Physics에서 Default Gravity Z를 -200.0으로 바꿉니다. 레벨에 큐브를 놓고 Simulate Physics를 켠 뒤 플레이하면, 큐브가 평소보다 느리게 떨어집니다. 이어서 큐브의 Enable Gravity를 끈 경우와 켠 경우를 비교합니다. 배율을 비교하고 싶다면 플레이어 캐릭터의 Character Movement에서 Gravity Scale을 1.0과 5.0으로 바꿔, 같은 처음 점프 조건에서 높이와 체공 시간을 비교합니다. 확인이 끝나면 프로젝트 중력을 -980.0으로 되돌립니다.
겹침 이벤트 받아 보기
먼저 겹침을 감지할 액터를 만듭니다. Actor를 부모로 BP_OverlapTest 블루프린트를 만들고, Static Mesh 컴포넌트에 Cube를 지정합니다. 이 컴포넌트의 Collision Presets를 OverlapAll로 바꾸며, 이때 Simulate Physics는 꺼 두는 편이 좋습니다. 큐브와 플레이어 캡슐 양쪽에서 Generate Overlap Events를 켜고, 서로의 채널이 Ignore가 아닌지 확인합니다.
다음으로 이벤트를 연결합니다. BP_OverlapTest의 이벤트 그래프에서 메시 컴포넌트의 OnComponentBeginOverlap 이벤트를 추가하고, 겹친 상대가 플레이어인지 거릅니다. 로컬 플레이어 한 명으로 연습한다면, 이벤트의 Other Actor와 Get Player Character(인덱스 0)의 반환값이 같은지 비교하고, 그 결과를 Branch에 넣어 True 쪽 실행만 Print String으로 연결합니다. Print String에는 Player Entered! 같은 메시지를 넣습니다.
이 블루프린트를 레벨에 놓고 플레이한 뒤, 플레이어 캐릭터로 큐브를 뚫고 지나가면 화면에 메시지가 나옵니다. 큐브가 너무 작아 잘 겹치지 않는다면 큐브의 크기를 키우거나, Box Collision 컴포넌트를 더해 충돌 영역만 키울 수 있습니다.
충돌 형상 보기
마지막으로 충돌 형상을 눈으로 확인합니다. 레벨에 SM_Chair처럼 비교적 복잡한 스태틱 메시를 놓고, 뷰포트의 Show 메뉴에서 Collision을 켜 충돌을 표시합니다. 스태틱 메시 에디터의 Simple Collision과 Complex Collision 표시도 함께 보며, 표시된 색만으로 충돌의 종류를 단정하지 않습니다.
그다음 Simulate Physics를 끈 정적인 비교용 메시에서, 스태틱 메시 에디터의 Collision Complexity를 Use Complex as Simple로 바꿔 봅니다. 그리고 캐릭터나 단순 충돌을 가진 물체가 그 메시에 닿는 위치가 어떻게 달라지는지 비교합니다. 이때도 표시만 보지 말고 실제로 닿는 위치를 확인합니다.
정리
- 프로젝트의 기본 중력은
Default Gravity Z(기본 -980.0 cm/s²)로 정하며, 절댓값이 작을수록 천천히 떨어지고 같은 점프가 더 높아집니다. - 액터의
Enable Gravity를 끄면 중력만 사라질 뿐 위치에 고정되지 않으며, 일반 강체에는 공통 중력 배율이 없고 캐릭터는 Character Movement의Gravity Scale을 씁니다. - 충돌 결과는 두 컴포넌트의 응답을 합쳐 정해지며, 한쪽이라도 Ignore면 무시되고, 둘 다 Block일 때만 막힙니다.
- 충돌 프리셋으로 대부분을 정하고, 필요하면
Custom...에서 Object Type과 응답을 직접 정하며, 새 Object Channel은 Project Settings의 Collision에서 추가합니다. - 단순 충돌은 효율적이라 대부분에 쓰고, 복잡 충돌은 정밀함이 꼭 필요한 곳에만 쓰며,
Use Complex as Simple인 메시는 물리 시뮬레이션을 할 수 없습니다. - 막히는 충돌과 Hit 알림, 겹침과 Overlap 알림은 별개라서, 각각의 이벤트 설정을 양쪽에서 맞춰야 합니다.
연습 문제
1. 총알이 벽을 통과한다
총알 컴포넌트는 WorldStatic에 Block으로 응답하도록 정했습니다. 그런데 벽 메시는 Projectile 오브젝트 타입에 Overlap으로 응답하도록 되어 있습니다. 총알이 벽에 막힐까요?
해설 보기
막히지 않습니다. 차단은 두 컴포넌트가 서로에 대해 모두 Block으로 응답할 때만 성립하는데, 벽이 총알에 Overlap으로 응답하므로 이 둘은 겹침만 감지합니다.
총알이 벽에 막히게 하려면 벽 쪽에서도 Projectile에 대한 응답을 Block으로 바꿔야 합니다. 그리고 막혔을 때 Hit 알림을 받으려면 그에 맞는 이벤트 설정도 함께 켭니다.
2. 중력을 껐는데 날아간다
움직이던 상자의 Enable Gravity를 실행 중에 껐더니, 상자가 공중에 멈추지 않고 그 방향으로 계속 날아갑니다. 왜 그럴까요?
해설 보기
중력을 끄면 중력의 영향만 사라질 뿐, 상자가 이미 가지고 있던 속도와 감쇠, 충돌, 외부의 힘은 계속 적용됩니다. 그래서 움직이던 상자는 중력 없이 그 속도로 계속 움직입니다.
공중에 멈추게 하려면 속도를 0으로 만들거나 감쇠를 크게 하거나, 물리 시뮬레이션 자체를 끄는 것처럼 다른 방법을 함께 써야 합니다.
3. 복잡 충돌로 바꿨더니 떨어지지 않는다
울퉁불퉁한 바위가 정확하게 부딪히게 하려고, 바위 메시의 Collision Complexity를 Use Complex as Simple로 바꾸고 Simulate Physics를 켰습니다. 그런데 바위가 물리로 떨어지지 않습니다. 왜 그럴까요? 어떻게 해야 할까요?
해설 보기
Use Complex as Simple은 단순 충돌을 요청하는 검사까지 폴리곤 메시로 처리하는 선택이라, 그렇게 설정한 메시는 물리 시뮬레이션을 할 수 없습니다.
움직이는 바위라면 Collision Complexity를 기본으로 되돌리고, Auto Convex Collision으로 볼록 껍질을 여러 개 만들어 형태를 비슷하게 맞춘 단순 충돌을 씁니다. 복잡 충돌은 움직이지 않는 정적인 환경에 정밀함이 꼭 필요할 때만 씁니다.
충돌 응답과 채널은 Epic의 충돌 개요에서 확인할 수 있습니다.
다음 글 물리 재질 설정 및 최적화에서는 마찰과 반발을 정하는 물리 재질을 자세히 다루고, 두 표면의 값이 어떻게 합쳐지는지 살펴봅니다.