PART 2 · 강의 2/3

Physics Constraint

UPhysicsConstraintComponent를 활용한 조인트, 모터, 파괴 가능 연결

01

Physics Constraint 개요

두 물리 바디를 연결하는 구속 조건

UPhysicsConstraintComponent는 두 개의 물리 바디를 연결하여 상대적 움직임을 제한하는 컴포넌트입니다. 경첩(Hinge), 볼 조인트(Ball Joint), 프리즘(Prismatic) 등 다양한 조인트 유형을 구현할 수 있습니다.

자유도(DOF) Linear (X/Y/Z) Angular (Swing1/Swing2/Twist) 조인트 유형
고정 (Fixed)모두 Locked모두 Locked용접, 고정 연결
경첩 (Hinge)모두 LockedTwist만 Limited/Free문, 뚜껑
볼 (Ball Socket)모두 LockedSwing Free, Twist Limited관절, 체인
프리즘 (Prismatic)1축만 Limited모두 Locked슬라이더, 피스톤
자유 (Free)모두 Free모두 Free제약 없음 (스프링만)
C++ - Physics Constraint 기본 설정
// 경첩 조인트 생성 예제 UPhysicsConstraintComponent* HingeConstraint; HingeConstraint = CreateDefaultSubobject<UPhysicsConstraintComponent>("HingeConstraint"); HingeConstraint->SetupAttachment(RootComponent); // 연결할 두 컴포넌트 지정 HingeConstraint->ComponentName1.ComponentName = "FrameMesh"; HingeConstraint->ComponentName2.ComponentName = "DoorMesh"; // Linear: 모두 잠금 HingeConstraint->SetLinearXLimit(ELinearConstraintMotion::LCM_Locked, 0); HingeConstraint->SetLinearYLimit(ELinearConstraintMotion::LCM_Locked, 0); HingeConstraint->SetLinearZLimit(ELinearConstraintMotion::LCM_Locked, 0); // Angular: Twist만 제한 범위 설정 (경첩) HingeConstraint->SetAngularSwing1Limit(EAngularConstraintMotion::ACM_Locked, 0); HingeConstraint->SetAngularSwing2Limit(EAngularConstraintMotion::ACM_Locked, 0); HingeConstraint->SetAngularTwistLimit(EAngularConstraintMotion::ACM_Limited, 90.0f);
02

Motor와 Drive

능동적으로 움직이는 Constraint

Constraint에 Motor(Drive)를 설정하면 수동적 제약을 넘어 능동적으로 목표 위치/속도를 추적하는 조인트를 만들 수 있습니다. 로봇 팔, 자동문, 물리 기반 애니메이션 등에 활용됩니다.

C++ - Angular Motor 설정
// 자동 닫히는 문 (Angular Motor) void APhysicsDoor::SetupDoorMotor() { // Angular Drive 활성화 Constraint->SetAngularDriveMode(EAngularDriveMode::TwistAndSwing); // Twist Drive 파라미터 Constraint->SetAngularDriveParams( 500.0f, // Spring (강도) - 높을수록 빨리 복원 50.0f, // Damping (감쇠) - 높을수록 진동 감소 0.0f // MaxForce (0 = 무한) ); // 목표 회전 설정 (닫힌 상태 = 0도) Constraint->SetAngularOrientationTarget(FRotator::ZeroRotator); } // 문 열기 (목표 회전 변경) void APhysicsDoor::OpenDoor() { Constraint->SetAngularOrientationTarget(FRotator(0, 90, 0)); } // Linear Motor 예제 (엘리베이터) void AElevator::SetupLinearMotor() { Constraint->SetLinearPositionDrive(false, false, true); // Z축만 Constraint->SetLinearDriveParams( 10000.0f, // Spring 1000.0f, // Damping 0.0f // MaxForce ); // 목표 위치 설정 Constraint->SetLinearPositionTarget(FVector(0, 0, 500.0f)); }
Drive 파라미터 효과 높은 값 낮은 값
Spring목표를 추적하는 강도빠르고 강한 복원느리고 부드러운 복원
Damping진동 억제진동 없이 도달목표 근처에서 진동
MaxForce최대 힘 제한 (0=무한)제한 없음외력에 의해 목표 이탈 가능
03

파괴 가능 Constraint

일정 힘 이상에서 끊어지는 연결

Constraint의 Breakable 옵션을 활성화하면 특정 힘이 가해졌을 때 연결이 끊어집니다. 체인, 로프, 부서지는 구조물 등에 활용됩니다.

C++ - 파괴 가능 Constraint
void ABreakableChain::SetupBreakableConstraint() { // 파괴 임계값 설정 Constraint->ConstraintInstance.ProfileInstance.bLinearBreakable = true; Constraint->ConstraintInstance.ProfileInstance.LinearBreakThreshold = 5000.0f; Constraint->ConstraintInstance.ProfileInstance.bAngularBreakable = true; Constraint->ConstraintInstance.ProfileInstance.AngularBreakThreshold = 3000.0f; // 파괴 이벤트 바인딩 Constraint->OnConstraintBroken.AddDynamic( this, &ABreakableChain::OnChainBroken ); } void ABreakableChain::OnChainBroken(int32 ConstraintIndex) { UE_LOG(LogTemp, Warning, TEXT("Constraint %d broken!"), ConstraintIndex); // 파괴 이펙트 스폰, 사운드 재생 등 }
Breakable Threshold 튜닝

LinearBreakThreshold의 단위는 kg*cm/s^2(뉴턴이 아님)입니다. 적절한 값을 찾으려면 p.Chaos.Solver.Joint.DebugDrawSettings 1 콘솔 명령으로 디버그 정보를 확인하면서 조절하세요.

04

런타임 Constraint 생성

C++에서 동적으로 물리 연결 만들기

C++ - 런타임에서 Constraint 동적 생성
void AGrappleHook::AttachToSurface(FHitResult& Hit) { // 런타임에 Constraint 컴포넌트 생성 UPhysicsConstraintComponent* NewConstraint = NewObject<UPhysicsConstraintComponent>(this); NewConstraint->RegisterComponent(); NewConstraint->AttachToComponent( RootComponent, FAttachmentTransformRules::KeepWorldTransform ); // 위치 설정 NewConstraint->SetWorldLocation(Hit.ImpactPoint); // Linear: Z축 제한 거리 내에서 자유 이동 (로프 길이) NewConstraint->SetLinearXLimit(ELinearConstraintMotion::LCM_Limited, 500.0f); NewConstraint->SetLinearYLimit(ELinearConstraintMotion::LCM_Limited, 500.0f); NewConstraint->SetLinearZLimit(ELinearConstraintMotion::LCM_Limited, 500.0f); // Angular: 자유 회전 NewConstraint->SetAngularSwing1Limit(EAngularConstraintMotion::ACM_Free, 0); NewConstraint->SetAngularSwing2Limit(EAngularConstraintMotion::ACM_Free, 0); NewConstraint->SetAngularTwistLimit(EAngularConstraintMotion::ACM_Free, 0); // 두 바디 연결 NewConstraint->SetConstrainedComponents( PlayerMesh, NAME_None, Hit.GetComponent(), Hit.BoneName ); ActiveConstraint = NewConstraint; }
SUMMARY

핵심 요약

  • UPhysicsConstraintComponent로 두 물리 바디를 다양한 방식(Fixed, Hinge, Ball, Prismatic)으로 연결합니다.
  • Linear/Angular Limit의 Locked/Limited/Free 조합으로 원하는 조인트 유형을 구현합니다.
  • Motor(Drive)로 Spring/Damping 기반의 능동적 목표 추적이 가능합니다.
  • Breakable Constraint로 일정 힘 이상에서 끊어지는 파괴 가능한 연결을 만들 수 있습니다.
  • SetConstrainedComponents()로 런타임에 동적으로 Constraint를 생성하고 연결할 수 있습니다.
PRACTICE

도전 과제

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

실습 1: 기본 Constraint 제작

Physics Constraint Actor를 사용하여 두 물리 객체를 Hinge Joint로 연결하세요. Angular Limit를 설정하여 문(Door)처럼 동작하는 오브젝트를 만들고, Angular Motor로 자동 닫히는 문을 구현하세요.

실습 2: 체인/로프 시뮬레이션

10개의 물리 박스를 Physics Constraint로 체인처럼 연결하세요. 각 Constraint의 Linear/Angular Limit과 Damping을 조정하고, 특정 힘 이상에서 끊어지는 Break Force를 설정하세요.

심화 과제: 파괴 가능한 구조물 시스템

C++로 벽돌벽을 Physics Constraint로 연결된 그리드 구조로 제작하세요. 각 Constraint에 Break Threshold를 설정하고, Impulse에 의한 연쇄 파괴 시스템을 구현하세요.