Unreal C++ - 부위 별 피격 판정
카테고리: Unreal
Unreal C++ - 부위 별 피격 구현
부위를 판정하고 싶은 만큼 Physical Material을 생성한다.
Project Settings의 Physics의 Physical Surface란에 이름이 동일한 Physical Surface들을 설정한다.
피격 당하는 객체의 PhysicsAsset의 부위마다 Physical Material을 설정한다.
C++ 코드에서 인식할 수 있도록 부위 이름과 EPhysicalSurfaceType을 이어주는 Map을 저장할 클래스를 생성한다
//header
class CPP_PORTFOLIO_API CBodyMap
{
private:
CBodyMap();
public:
UPROPERTY(BlueprintReadOnly)
static const TMap<FString, FString> Map;
};
//cpp
const TMap<FString, FString> CBodyMap::Map = {
{"Body", "SurfaceType1"},
{"Head", "SurfaceType2"}
};
무기와 피격 당하는 객체와의 BeginOverlap 이벤트에서 부위를 판별한다.
IIDamageable이라는 인터페이스를 상속 받았는지 확인하여 피해를 입을 수 있는 객체인지 확인 후, Overlap 이벤트에서 들어오는 InOtherBodyIndex가 -1인 경우는 Physical Material을 판별할 수 없으므로 return한다.
IIDamageable* character = Cast<IIDamageable>(InOther);
if (character == nullptr || InOtherBodyIndex == -1)
return;
InOtherBodyIndex를 여러번 가져오기 위해 Overlap Event를 여러번 발생시켜야 하기 때문에 Multi Overlap Event를 활성화한다.
InOtherBodyIndex가 -1이 아닌 경우 Physical Material이 할당된 BodyInstance를 피격 당한 객체의 USkeletalMeshComponent로 부터 확인할 수 있다.
BodyInstance의 Physical Material을 가져오면 할당된 Material의 이름을 가져올 수 있으며, CBodyMap으로 이를 FString으로 적인 SurfaceType으로 변경하고 FindObject를 통해 EPhysicalSurface로 변경하여 피격 당하는 객체에게 어느 부위를 피격 당하였는지 알린다.
//연속 피격 방지를 위한 Hitted 배열 검사
for (IIDamageable* hitted : Hitted)
{
if (hitted == character)
return;
}
USkeletalMeshComponent* comp = Cast<USkeletalMeshComponent>(InOtherComp);
if (!!comp)
{
FBodyInstance* BodyInstance = comp->GetBodyInstance(comp->GetBoneName(InOtherBodyIndex));
if (BodyInstance != nullptr)
{
UPhysicalMaterial* physmat = BodyInstance->GetSimplePhysicalMaterial();
Hitted.AddUnique(character);
const UEnum* enumProperty = FindObject<UEnum>(ANY_PACKAGE, TEXT("EPhysicalSurface"), true);
if(!!enumProperty)
{
FString str = CBodyMap::Map[physmat->GetName()];
int32 index = enumProperty->GetIndexByNameString(str);
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, physmat->GetName());
EPhysicalSurface type = EPhysicalSurface((uint8)index);
character->TakeDamage(HitData, type);
}
}
}