PART 1 · 강의 2/3

Rigid Body 시뮬레이션

FBodyInstance를 통한 강체 시뮬레이션의 핵심 파라미터와 제어 방법

01

FBodyInstance와 Simulate Physics

강체 물리의 출발점

UE5에서 물리 시뮬레이션의 기본 단위는 FBodyInstance입니다. 모든 UPrimitiveComponent는 하나 이상의 FBodyInstance를 가지며, 이를 통해 Chaos 솔버와 상호작용합니다.

C++ - Simulate Physics 활성화
// StaticMeshComponent에서 물리 시뮬레이션 활성화 UStaticMeshComponent* MeshComp = CreateDefaultSubobject<UStaticMeshComponent>("MeshComp"); MeshComp->SetSimulatePhysics(true); // FBodyInstance에 직접 접근 FBodyInstance* Body = MeshComp->GetBodyInstance(); if (Body) { Body->bSimulatePhysics = true; Body->SetMassOverrideInKg(NAME_None, 50.0f, true); Body->SetLinearVelocity(FVector(0, 0, 500.0f)); }
FBodyInstance 속성 타입 설명 기본값
bSimulatePhysics bool 물리 시뮬레이션 활성화 false
MassInKgOverride float 질량 오버라이드 (kg) 자동 계산
LinearDamping float 선형 감쇠 (이동 저항) 0.01
AngularDamping float 각 감쇠 (회전 저항) 0.0
bEnableGravity bool 중력 적용 여부 true
bLockXRotation bool X축 회전 잠금 false
질량 자동 계산

MassInKgOverride를 설정하지 않으면 엔진이 콜리전 형상의 체적 x 밀도로 질량을 자동 계산합니다. Physical Material의 Density 값이 이 계산에 영향을 줍니다. 의도치 않게 매우 큰 질량이 설정될 수 있으므로, 중요한 물리 객체는 질량을 명시적으로 지정하는 것이 좋습니다.

02

힘과 충격량 적용

AddForce, AddImpulse, AddTorque의 차이와 활용

리지드 바디에 운동을 가하는 방법은 크게 힘(Force), 충격량(Impulse), 토크(Torque)로 나뉩니다. 각각의 특성을 이해하고 상황에 맞게 사용해야 합니다.

메서드 단위 적용 방식 사용 예시
AddForce() N (뉴턴) 매 프레임 누적, DeltaTime 의존 엔진 추력, 바람, 지속적 밀기
AddImpulse() kg*cm/s 즉시 속도 변경, 단발성 폭발, 점프, 총알 충격
AddTorqueInRadians() N*cm 회전력 적용, 매 프레임 누적 프로펠러, 팽이 회전
AddAngularImpulseInRadians() kg*cm^2/s 즉시 각속도 변경 충돌 후 회전, 스핀 공격
AddForceAtLocation() N 특정 위치에 힘 적용 (토크 유발) 비대칭 충격, 로켓 추력
C++ - 힘과 충격량 적용 예제
// 지속적인 힘 적용 (Tick에서 호출) void APhysicsActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); // 위쪽으로 지속적인 힘 (로켓 추력처럼) MeshComp->AddForce( FVector(0, 0, 980.0f) * MeshComp->GetMass(), NAME_None, false // bAccelChange = false: 질량에 영향받음 ); } // 순간 충격량 적용 (이벤트에서 호출) void APhysicsActor::OnExplosion(FVector ExplosionOrigin) { FVector Direction = GetActorLocation() - ExplosionOrigin; Direction.Normalize(); // 폭발 충격 - 즉시 속도 변경 MeshComp->AddImpulse( Direction * 5000.0f, NAME_None, true // bVelChange = true: 질량 무시, 순수 속도 변경 ); }
bAccelChange / bVelChange 파라미터

bAccelChange=true로 설정하면 질량에 관계없이 동일한 가속도를 적용합니다. 마찬가지로 bVelChange=true는 질량과 무관하게 속도를 직접 변경합니다. 질량이 다른 다양한 오브젝트에 동일한 효과를 주고 싶을 때 유용합니다.

03

질량, 관성 텐서, 무게중심

강체 물리의 핵심 물성

리지드 바디의 동작은 질량(Mass), 관성 텐서(Inertia Tensor), 무게중심(Center of Mass) 세 가지 물성에 의해 결정됩니다.

C++ - 질량과 관성 텐서 제어
void APhysicsActor::ConfigurePhysicsBody() { FBodyInstance* Body = MeshComp->GetBodyInstance(); // 질량 설정 (kg) Body->SetMassOverrideInKg(NAME_None, 100.0f, true); // 무게중심 오프셋 (로컬 좌표) Body->COMNudge = FVector(0, 0, -20.0f); // 아래로 이동 → 안정적 // 관성 텐서 스케일 (기본값: 1,1,1) Body->InertiaTensorScale = FVector(1.0f, 1.0f, 0.5f); // Z축 관성 감소 → Z축 회전이 더 쉬워짐 // 질량 정보 업데이트 Body->UpdateMassProperties(); // 현재 질량 확인 float Mass = Body->GetBodyMass(); FVector COM = Body->GetCOMPosition(); UE_LOG(LogTemp, Log, TEXT("Mass: %f kg, COM: %s"), Mass, *COM.ToString()); }
물성 효과 게임 플레이 영향
질량 증가 같은 힘에 대해 덜 움직임 무거운 느낌, 충돌 시 상대를 밀어냄
COM 아래로 이동 복원력 증가 쓰러지지 않는 안정적 오브젝트
COM 위로 이동 불안정한 균형 쉽게 넘어지는 오브젝트
관성 텐서 축소 해당 축 회전이 쉬움 빠른 회전, 반응적 움직임
관성 텐서 확대 해당 축 회전에 저항 느린 회전, 무거운 느낌
UE5의 단위 체계

UE5에서 거리는 cm, 질량은 kg, 시간은 초(s)를 사용합니다. 따라서 힘의 단위는 kg*cm/s^2이고, 충격량은 kg*cm/s입니다. 기본 중력 가속도는 -980 cm/s^2 (= -9.8 m/s^2)입니다.

04

감쇠, 잠금, Sleep

시뮬레이션 제어와 성능 최적화

실제 게임에서는 무한히 움직이는 물리 객체보다, 적절히 감쇠되고 정지하는 객체가 필요합니다. Damping, Lock, Sleep 메커니즘으로 이를 제어합니다.

C++ - 감쇠와 잠금 설정
void APhysicsActor::SetupDamping() { FBodyInstance* Body = MeshComp->GetBodyInstance(); // 선형 감쇠: 0 = 감쇠 없음, 높을수록 빨리 정지 Body->LinearDamping = 0.5f; // 각 감쇠: 회전 저항 Body->AngularDamping = 1.0f; // 최대 속도 제한 Body->MaxAngularVelocity = 3600.0f; // degree/s // 축별 이동 잠금 Body->bLockXTranslation = false; Body->bLockYTranslation = false; Body->bLockZTranslation = true; // Z축 이동 잠금 (2D 게임용) // 축별 회전 잠금 Body->bLockXRotation = true; Body->bLockYRotation = true; Body->bLockZRotation = false; // Z축 회전만 허용 Body->UpdateMassProperties(); } // Sleep 상태 제어 void APhysicsActor::ManageSleep() { FBodyInstance* Body = MeshComp->GetBodyInstance(); // Sleep 임계값 설정 Body->SleepFamily = ESleepFamily::Normal; // 수동으로 깨우기 Body->WakeInstance(); // 수동으로 재우기 Body->PutInstanceToSleep(); }
Sleep은 성능의 핵심

정지 상태의 물리 객체는 자동으로 Sleep 상태에 들어가 시뮬레이션 비용이 거의 0이 됩니다. 수백 개의 물리 객체가 있는 씬에서도 움직이는 객체만 연산하므로 성능이 유지됩니다. SleepFamily를 Sensitive로 설정하면 더 빠르게 잠들지만, Custom을 사용해 직접 임계값을 지정할 수도 있습니다.

SUMMARY

핵심 요약

  • FBodyInstance는 UE5 물리 시뮬레이션의 기본 단위이며, 모든 UPrimitiveComponent에 존재합니다.
  • Force는 매 프레임 누적되는 지속적 힘, Impulse는 즉시 속도를 변경하는 단발성 충격입니다.
  • 질량, 관성 텐서, 무게중심이 강체의 동적 특성을 결정합니다.
  • Damping으로 감속을, Lock으로 축별 자유도를 제한하고, Sleep으로 성능을 최적화합니다.
  • bAccelChange/bVelChange 플래그를 사용하면 질량과 무관한 균일한 물리 효과를 줄 수 있습니다.
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: FBodyInstance 파라미터 실험

Static Mesh Actor 5개를 레벨에 배치하고 각각 다른 Mass(1kg, 10kg, 50kg, 100kg, 500kg)를 설정하세요. 동일한 Impulse를 가해 질량에 따른 반응 차이를 비교하세요.

실습 2: Damping과 Sleep 테스트

경사면 위에 박스를 배치하고 Linear Damping(0, 0.5, 2.0, 5.0)과 Angular Damping(0, 1.0, 5.0)을 조합하여 미끄러짐/굴림 특성의 차이를 관찰하세요. Sleep 상태 전환 시점도 확인하세요.

심화 과제: Force vs Impulse 시각화 시스템

C++로 AddForce와 AddImpulse를 매 프레임 시각화하는 디버그 액터를 구현하세요. 힘의 방향과 크기를 화살표로 표시하고, 속도 벡터 변화를 그래프로 기록하는 시스템을 만드세요.