4.21 피직스 테크니컬 노트

언리얼 엔진 4.21 의 피직스 인터페이스에 가해진 변경사항 관련 기술적인 내용입니다.

Windows
MacOS
Linux

언리얼 엔진 4.21 버전에 있었던 피직스 시스템에 대한 리팩터링 관련 개요서입니다.

언리얼 엔진 4.21 버전에서 Physics Interface (피직스 인터페이스)를 리팩터링하여 보다 세밀한 수준이 아닌 일반적인 관점에서의 피직스 오브젝트 소유권을 지원하도록 했습니다. 이 변경 결과 APEX Destruction 에만 사용을 권하던 Async Scene (비동기 씬) 기능이 폐기되었습니다. 여전히 Sync Scene (동기 씬) 기능을 사용하여 동일한 시각적 결과를 얻을 수 있습니다.

이 변경으로 인해 피직스 관련 C++ 코드 API 다수가 리팩터링되었습니다. 기능적으로 API 는 동일하므로 현재 사용하는 방식과 매우 유사하게 사용할 수 있을 것입니다. 여기서는 무엇이 리팩터링되었는지, 참조용 파일을 어디서 찾을 수 있는지를 설명합니다.

비동기 씬 폐기

Async Scene (비동기 씬)은 Apex Destruction 바디 저장을 위해 잠시 사용했던 기능입니다. 그 바디는 한 프레임 뒤까지 실행되고 엔진은 다음 프레임에서야 그 결과를 구하곤 했습니다.

여기에 문제점은 그 관리를 처리하는 (즉 비동기가 이건 하고 저건 안하고 하는 if) 코드만 해도 많은 데다 디스트럭션 씬에 바디가 많은 경우, 게임 스레드에 영향을 줄 수 있었습니다. 또한 비동기 씬의 바디는 게임플레이 또는 동기 씬의 다른 바디와 상호 작용할 수 없었습니다.

비동기 씬을 폐기했다고 디스트럭션이 작동하지 않는다는 뜻은 아니라 그 비동기 씬 부분만 더이상 지원하지 않는다는 뜻입니다. 디스트럭션은 완전 정상 작동하며, 이제 메인 피직스 씬의 일부처럼 작동합니다.

피직스 인터페이스

피직스 인터페이스는 크게 두 가지 기능을 제공합니다.

  1. 종속성 쳬계 정리 - 엔진은 더이상 PhysX 로 직접 호출하지 않습니다. 대신 모든 피직스 관련 호출은 피직스 인터페이스를 통합니다.

  2. 피직스 상호 작용의 공통 모델 생성 - 피직스 인터페이스는 언리얼과의 상호 작용을 위한 공통된 방법의 피직스 솔루션을 제공합니다.

설치 폴더 내 Engine/Source/Runtime/Engine/Public/Physics 아래 있는 여러 피직스 인터페이스 파일의 코드 변경사항을 검토해 볼 수 있습니다. The Engine/Source/Runtime/Engine/Public/Physics/PhysicsInterfacePhysX 파일에는 언리얼이 관련 PhysX 를 호출하는 데 필요할 수도 있는 모든 함수 정의 전체가 들어있습니다.

프로젝트가 FBodyInstance 내 PhysX 오브젝트를 직접 조작하지 않는다면 아무런 부작용이 없을 것입니다. FBodyinstance 에 노출된 메서드는 새 인터페이스를 사용해 전부 재구현했으며, 이전 버전과 똑같은 방식으로 사용됩니다.

직접 PhysX 데이터를 조작하거나 PhysX 유형 등과 상호작용하는 코드는 새 API 를 사용하도록 하는 리팩터링이 필요합니다. FBodyInstance::SetLinearVelocity 함수에서 예제를 확인할 수 있습니다.

4.20:

void FBodyInstance::SetLinearVelocity(const FVector& NewVel, bool bAddToCurrent)
{
#if WITH_PHYSX
    ExecuteOnPxRigidBodyReadWrite(this, [&](PxRigidBody* PRigidBody)
    {
        PxVec3 PNewVel = U2PVector(NewVel);
        if (bAddToCurrent)
        {
            const PxVec3 POldVel = PRigidBody->getLinearVelocity();
            PNewVel += POldVel;
        }
        PRigidBody->setLinearVelocity(PNewVel);
    });
#endif // WITH_PHYSX
}

4.21:

void FBodyInstance::SetLinearVelocity(const FVector& NewVel, bool bAddToCurrent, bool bAutoWake)
{
    FPhysicsCommand::ExecuteWrite(ActorHandle, [&](const FPhysicsActorHandle& Actor)
    {
        if(FPhysicsInterface::IsRigidBody(Actor))
        {
            FVector FinalVelocity = NewVel;
            if(bAddToCurrent)
            {
                FinalVelocity += FPhysicsInterface::GetLinearVelocity_AssumesLocked(Actor);
            }
            FPhysicsInterface::SetLinearVelocity_AssumesLocked(Actor, FinalVelocity);
        }
    });
}

새 버전에서도 로직은 똑같지만 코드가 PhysX 유형이 아닌 독립 핸들을 사용합니다.

Engine/Source/Runtime/Engine/Public/Physics/PhysicsInterfaceCore 파일은 지원하는 다양한 인터페이스를 전부 빌드하는 반면 Engine/Source/Runtime/Engine/Public/Physics/PhysicsInterfaceDeclares 파일은 통신에 사용되는 유형이 들어있습니다. 단순한 유형, 예를 들어 FPhysicsActorHandle 를 사용하여 액터와 통신해도 내부적으로 엔진은 파생형을 이해합니다.

현재 지원하여 작동되는 것은 PhysicsInterfacePhysX 뿐입니다. 다른 모든 것은 초기 실험단계로 간주되며, 예상대로 작동하지 않을 수 있습니다.

새로운 언리얼 엔진 4 문서 사이트에 오신 것을 환영합니다!

문서 사이트에 대한 의견을 모을 수 있는 피드백 시스템을 포함해서 여러가지 새로운 기능을 준비하고 있습니다. 아래 Documentation Feedback 포럼(영문) 또는 언리얼 엔진 네이버 공식 카페(한글) 중 편하신 곳에 의견이나 문제점을 알려 주세요.

새 시스템이 준비되면 알려 드리겠습니다.

네이버 카페
공식 포럼