콘텐츠로 이동

UE5 Chaos Physics 활용 완전 가이드

UE5의 Chaos Physics는 PhysX를 대체하는 차세대 물리 엔진입니다. 대규모 강체 시뮬레이션, 리얼타임 파괴 효과(Chaos Destruction), 천 시뮬레이션(Cloth), 차량 물리(Chaos Vehicle)를 통합된 시스템으로 제공합니다.


// 물리 컴포넌트 설정
UCLASS()
class APhysicsObject : public AActor
{
GENERATED_BODY()
UPROPERTY(VisibleAnywhere)
TObjectPtr<UStaticMeshComponent> MeshComp;
public:
APhysicsObject()
{
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
RootComponent = MeshComp;
// 물리 시뮬레이션 활성화
MeshComp->SetSimulatePhysics(true);
MeshComp->SetMassOverrideInKg(NAME_None, 10.f); // 10kg
MeshComp->SetLinearDamping(0.1f);
MeshComp->SetAngularDamping(0.1f);
}
};

// 힘 적용 (지속적)
void ApplyForces()
{
// 질량에 무관한 힘 (NewtonSecond / kg)
MeshComp->AddForce(FVector(0, 0, 980.f), NAME_None, /*bAccelChange=*/true);
// 특정 지점에 힘 적용
MeshComp->AddForceAtLocation(
FVector(1000.f, 0.f, 0.f),
MeshComp->GetComponentLocation() + FVector(0, 0, 50),
NAME_None);
// 토크 (회전력)
MeshComp->AddTorqueInRadians(FVector(0, 0, 100.f), NAME_None, true);
}
// 임펄스 (순간적 힘)
void ApplyImpulse(const FVector& Direction, float Strength)
{
MeshComp->AddImpulse(Direction.GetSafeNormal() * Strength, NAME_None, true);
// 히트 위치에 임펄스 (폭발 효과)
FVector ExplosionCenter = GetActorLocation() + FVector(0, 0, -50.f);
MeshComp->AddRadialImpulse(ExplosionCenter, 500.f, 2000.f,
RIF_Linear, /*bVelChange=*/true);
}

3. Chaos Destruction — 파괴 가능 메시

섹션 제목: “3. Chaos Destruction — 파괴 가능 메시”
// Geometry Collection 컴포넌트
UCLASS()
class ADestructibleWall : public AActor
{
GENERATED_BODY()
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
TObjectPtr<UGeometryCollectionComponent> GeometryCollection;
public:
ADestructibleWall()
{
GeometryCollection = CreateDefaultSubobject<UGeometryCollectionComponent>(
TEXT("GeometryCollection"));
RootComponent = GeometryCollection;
// 충격 임계값 설정
GeometryCollection->SetNotifyBreaks(true);
}
void BeginPlay() override
{
Super::BeginPlay();
GeometryCollection->OnChaosBreakEvent.AddDynamic(
this, &ADestructibleWall::OnBreak);
}
UFUNCTION()
void OnBreak(const FChaosBreakEvent& BreakEvent)
{
UE_LOG(LogTemp, Log, TEXT("파괴 발생 위치: %s"),
*BreakEvent.Location.ToString());
// 파괴 이펙트, 사운드 재생
}
};

// 폭발 필드 적용 — 주변 오브젝트에 방사형 힘
void AExplosionActor::Explode()
{
// 방사형 힘 필드 생성
ARadialFalloffField* ForceField = GetWorld()->SpawnActor<ARadialFalloffField>(
GetActorLocation(), FRotator::ZeroRotator);
// 파괴 타입 필드 설정
UFieldSystemComponent* FieldComp = GetWorld()->SpawnActor<AFieldSystemActor>(
GetActorLocation(), FRotator::ZeroRotator)
->GetFieldSystemComponent();
// 임펄스 필드 (폭발력)
URadialFalloff* Falloff = NewObject<URadialFalloff>();
Falloff->Radius = 500.f;
Falloff->Magnitude = 1.f;
Falloff->MinRange = 0.f;
Falloff->MaxRange = 1.f;
Falloff->Position = GetActorLocation();
FieldComp->ApplyPhysicsField(true, EFieldPhysicsType::Field_LinearForce,
nullptr, Falloff);
}

// 두 액터를 연결하는 물리 제약
UCLASS()
class ARopeSegment : public AActor
{
GENERATED_BODY()
UPROPERTY(VisibleAnywhere)
TObjectPtr<UPhysicsConstraintComponent> Constraint;
UPROPERTY(VisibleAnywhere)
TObjectPtr<UStaticMeshComponent> MeshComp;
public:
void ConnectTo(UStaticMeshComponent* OtherComp)
{
Constraint->SetConstrainedComponents(MeshComp, NAME_None, OtherComp, NAME_None);
// 스윙 제한 설정 (로프처럼)
Constraint->SetAngularSwing1Limit(ACM_Limited, 45.f);
Constraint->SetAngularSwing2Limit(ACM_Limited, 45.f);
Constraint->SetAngularTwistLimit(ACM_Free, 0.f);
}
void Break()
{
Constraint->BreakConstraint();
}
};

// 물리 필터링 설정
void SetupPhysicsFiltering()
{
FCollisionResponseContainer ResponseContainer;
ResponseContainer.SetAllChannels(ECR_Ignore);
ResponseContainer.SetResponse(ECC_WorldStatic, ECR_Block);
ResponseContainer.SetResponse(ECC_Pawn, ECR_Overlap);
MeshComp->SetCollisionResponseToChannels(ResponseContainer);
// 물리 재질 설정
UPhysicalMaterial* PhysMat = NewObject<UPhysicalMaterial>();
PhysMat->Friction = 0.8f;
PhysMat->Restitution = 0.2f; // 탄성
PhysMat->Density = 1.0f;
MeshComp->SetPhysMaterialOverride(PhysMat);
}

7. AsyncPhysics — 비동기 물리 콜백

섹션 제목: “7. AsyncPhysics — 비동기 물리 콜백”
// 물리 스레드 콜백 (고성능)
UCLASS()
class APhysicsActor : public AActor, public IPhysicsInterface
{
GENERATED_BODY()
virtual void AsyncPhysicsTickActor(
float DeltaTime, float SimTime) override
{
// 물리 스레드에서 호출 (Main Thread와 분리)
// 힘 적용, 속도 쿼리 등 물리 작업
FVector Velocity = MeshComp->GetPhysicsLinearVelocity();
if (Velocity.Z < -1000.f)
{
// 낙하 속도 제한
Velocity.Z = -1000.f;
MeshComp->SetPhysicsLinearVelocity(Velocity);
}
}
};

기능클래스/컴포넌트
강체 시뮬레이션UStaticMeshComponent::SetSimulatePhysics
파괴 효과UGeometryCollectionComponent
물리 필드UFieldSystemComponent
물리 제약UPhysicsConstraintComponent
차량 물리UChaosVehicleMovementComponent