Physical Material
표면 물성(마찰, 반발), Surface Type, 질량 밀도 설정
Physical Material이란
표면의 물리적 특성 정의
UPhysicalMaterial은 표면의 물리적 속성을 정의하는 에셋입니다. 마찰계수, 반발계수, 밀도 등을 설정하여 다양한 재질(얼음, 고무, 금속 등)의 물리적 느낌을 표현합니다.
| 속성 | 범위 | 설명 | 예시 |
|---|---|---|---|
Friction | 0.0 ~ 1.0+ | 동마찰 계수 (미끄러짐 저항) | 얼음: 0.05, 고무: 0.8 |
StaticFriction | 0.0 ~ 1.0+ | 정마찰 계수 (움직이기 시작하는 저항) | 일반: Friction보다 약간 높음 |
Restitution | 0.0 ~ 1.0 | 반발 계수 (튕김 정도) | 점토: 0.0, 공: 0.7 |
Density | g/cm^3 | 밀도 (자동 질량 계산에 사용) | 물: 1.0, 철: 7.8 |
RaiseMassToPower | 0.0 ~ 1.0 | 질량 스케일링 지수 | 0.75 (기본값) |
두 표면이 접촉할 때 마찰 계수는 Friction Combine Mode로 계산됩니다: Average(평균), Min(최솟값), Multiply(곱), Max(최댓값). 기본은 Average입니다. 프로젝트 설정에서 전역으로 변경하거나, Physical Material에서 개별 설정할 수 있습니다.
Surface Type 시스템
재질별 이펙트와 사운드 분기
Surface Type은 물리적 속성이 아닌 게임 로직용 태그입니다. 충돌한 표면이 어떤 재질인지 판별하여, 재질에 맞는 파티클 이펙트, 사운드, 데칼 등을 재생하는 데 사용합니다.
// Project Settings > Physics > Physical Surface에서 커스텀 Surface Type 추가
// 또는 DefaultEngine.ini에서 직접 정의:
// [/Script/Engine.PhysicsSettings]
// +PhysicalSurfaces=(Type=SurfaceType1, Name="Wood")
// +PhysicalSurfaces=(Type=SurfaceType2, Name="Metal")
// +PhysicalSurfaces=(Type=SurfaceType3, Name="Concrete")
// Surface Type에 따른 이펙트 분기
void AWeapon::SpawnImpactEffect(const FHitResult& Hit)
{
// Physical Material에서 Surface Type 가져오기
EPhysicalSurface SurfaceType = UPhysicalMaterial::DetermineSurfaceType(
Hit.PhysMaterial.Get()
);
UParticleSystem* ImpactFX = nullptr;
USoundBase* ImpactSound = nullptr;
switch (SurfaceType)
{
case SurfaceType1: // Wood
ImpactFX = WoodImpactFX;
ImpactSound = WoodImpactSound;
break;
case SurfaceType2: // Metal
ImpactFX = MetalImpactFX;
ImpactSound = MetalImpactSound;
break;
case SurfaceType3: // Concrete
ImpactFX = ConcreteImpactFX;
ImpactSound = ConcreteImpactSound;
break;
default:
ImpactFX = DefaultImpactFX;
ImpactSound = DefaultImpactSound;
break;
}
// 이펙트 스폰
UGameplayStatics::SpawnEmitterAtLocation(
GetWorld(), ImpactFX, Hit.ImpactPoint, Hit.ImpactNormal.Rotation()
);
}
LineTrace에서 Physical Material 정보를 받으려면 FCollisionQueryParams::bReturnPhysicalMaterial = true로 설정해야 합니다. 기본값은 false이므로 잊지 마세요.
Physical Material 적용 방법
다양한 적용 경로와 우선순위
- Phys Material Override — 컴포넌트의 Collision 섹션에서 직접 오버라이드. 최우선 적용됩니다.
- Material의 Physical Material — 렌더링 Material 에셋에 설정된 Physical Material.
- Static Mesh의 Simple Collision Physical Material — Static Mesh 에디터의 Body Setup에 설정.
- Physics Asset Body의 Physical Material — Skeletal Mesh의 Physics Body별 설정.
// 1. 컴포넌트에 직접 오버라이드
UPhysicalMaterial* IceMaterial = LoadObject<UPhysicalMaterial>(
nullptr, TEXT("/Game/Physics/PM_Ice")
);
MeshComp->SetPhysMaterialOverride(IceMaterial);
// 2. Physical Material을 C++에서 동적 생성
UPhysicalMaterial* DynMaterial = NewObject<UPhysicalMaterial>();
DynMaterial->Friction = 0.1f;
DynMaterial->Restitution = 0.0f;
DynMaterial->Density = 0.9f;
MeshComp->SetPhysMaterialOverride(DynMaterial);
// 3. 런타임에서 현재 Physical Material 확인
FBodyInstance* Body = MeshComp->GetBodyInstance();
UPhysicalMaterial* CurrentMat = Body->GetSimplePhysicalMaterial();
if (CurrentMat)
{
UE_LOG(LogTemp, Log, TEXT("Friction: %f, Restitution: %f"),
CurrentMat->Friction, CurrentMat->Restitution);
}
재질별 프리셋 가이드
게임에서 자주 사용하는 재질 설정값
| 재질 | Friction | Restitution | Density | 특징 |
|---|---|---|---|---|
| 콘크리트 | 0.6 | 0.1 | 2.4 | 높은 마찰, 낮은 반발 |
| 금속 | 0.4 | 0.3 | 7.8 | 중간 마찰, 약간의 반발 |
| 나무 | 0.5 | 0.2 | 0.6 | 중간 마찰, 가벼움 |
| 유리 | 0.3 | 0.5 | 2.5 | 낮은 마찰, 높은 반발 |
| 얼음 | 0.05 | 0.1 | 0.9 | 매우 낮은 마찰 |
| 고무 | 0.8 | 0.7 | 1.1 | 높은 마찰과 반발 |
| 흙/모래 | 0.6 | 0.0 | 1.5 | 높은 마찰, 반발 없음 |
| 물웅덩이 | 0.2 | 0.0 | 1.0 | 낮은 마찰, 반발 없음 |
위 값들은 현실 물리를 기반으로 하지만, 게임에서는 느낌(feel)이 더 중요합니다. 물리적으로 정확한 값이 반드시 좋은 게임플레이를 보장하지 않습니다. 플레이 테스트를 통해 재미있는 값을 찾는 것이 중요합니다.
핵심 요약
UPhysicalMaterial로 마찰(Friction), 반발(Restitution), 밀도(Density)를 설정합니다.- Surface Type은 물리 속성이 아닌 게임 로직용 태그로, 재질별 이펙트/사운드 분기에 사용합니다.
- 적용 우선순위: Phys Material Override > Material 설정 > Mesh Body Setup.
- 마찰 조합은 Friction Combine Mode(Average, Min, Multiply, Max)로 계산됩니다.
- 현실적 값보다 게임적 느낌을 우선하여 플레이 테스트로 튜닝하는 것이 중요합니다.
도전 과제
배운 내용을 직접 실습해보세요
Ice(마찰 0.05, 반발 0.1), Rubber(마찰 0.8, 반발 0.7), Metal(마찰 0.3, 반발 0.2), Wood(마찰 0.5, 반발 0.3) 4가지 Physical Material을 생성하고 각각 Surface Type을 할당하세요.
OnHit 이벤트에서 Physical Material의 Surface Type을 읽어 충돌 시 다른 파티클과 사운드를 재생하는 시스템을 블루프린트로 구현하세요.
비, 기름 등 환경 조건에 따라 Physical Material의 마찰 계수를 런타임에서 동적으로 변경하는 시스템을 C++로 구현하세요. 영역 트리거와 결합하여 특정 구역에서 표면 속성이 자동으로 바뀌도록 하세요.