UE4之PVD调试
PhysX在编译时必须开启PX_SUPPORT_PVD宏(PhysX的Debug、Profiler版本的库会开启该宏),才能支持 PVD 的调试。
游戏缺省会使用localhost,端口为5425,连接超时时间为100ms来与Physx Visual Debugger工具建立连接。
如果要修改PVD的端口号,只能修改pvd.exe的31150000(为5425的16进制小端序)数值,如下:
引擎连接PVD的逻辑在:UnrealEngine\Engine\Source\Runtime\PhysicsCore\Private\PhysXSupportCore.cpp的void PvdConnect(FString Host, bool bVisualization)函数中。
注意
1. 在使用PVD之前,必须先启动Physx Visual Debugger工具。
2. 不可同时运行多个PVD进程(打开任务管理器进行确认)
通过命令行参数连接Physx Visual Debugger工具
UE4Editor.exe "%GameDir%\MyGame.uproject" TestMap_Main -game -pvd // 单机启动TestMap_Main地图,并自动连接本机正在运行的PhysX Visual Debugger
通过控制台命令连接Physx Visual Debugger工具
pvd CONNECT // 连接本机正在运行的PVD 注:调用void PvdConnect(FString Host, bool bVisualization)函数
pvd CONNECT 10.46.80.77 // 连接ip为10.46.80.77上正在运行的PVD 注:缺省端口为5425,连接超时时间为100ms
pvd CONNECT NODEBUG 10.46.80.77 // 连接ip为10.46.80.77上正在运行的PVD,仅用于profile和meomry,不绘制 注:缺省端口为5425,连接超时时间为100ms
pvd DISCONNECT // 断开与PVD的连接
Physx Visual Debugger主界面
注:使用左手系(Left-Handed),与虚幻引擎保证画面一致
线框模式:
在Physx Visual Debugger中不同rigid(刚体)的颜色
在Physx Visual Debugger中实时查看游戏的物理
在编辑器Preview模式下所有物体都会创建物理对象
> UE4Editor-Engine-Win64-Debug.dll!UPrimitiveComponent::ShouldCreatePhysicsState() Line 1409 C++ UE4Editor-Engine-Win64-Debug.dll!UActorComponent::CreatePhysicsState(bool bAllowDeferral=true) Line 1462 C++ UE4Editor-Engine-Win64-Debug.dll!UActorComponent::ExecuteRegisterEvents(FRegisterComponentContext * Context=0x0000000000000000) Line 1537 C++ UE4Editor-Engine-Win64-Debug.dll!UActorComponent::RegisterComponentWithWorld(UWorld * InWorld=0x0000024082b9b580, FRegisterComponentContext * Context=0x0000000000000000) Line 1223 C++ UE4Editor-Engine-Win64-Debug.dll!AActor::IncrementalRegisterComponents(int NumComponentsToRegister=2147483647, FRegisterComponentContext * Context=0x0000000000000000) Line 4582 C++ UE4Editor-Engine-Win64-Debug.dll!ULevel::IncrementalUpdateComponents(int NumComponentsToUpdate=0, bool bRerunConstructionScripts=true, FRegisterComponentContext * Context=0x0000000000000000) Line 1094 C++ UE4Editor-Engine-Win64-Debug.dll!ULevel::UpdateLevelComponents(bool bRerunConstructionScripts=true, FRegisterComponentContext * Context=0x0000000000000000) Line 971 C++ UE4Editor-Engine-Win64-Debug.dll!UWorld::UpdateWorldComponents(bool bRerunConstructionScripts=true, bool bCurrentLevelOnly=true, FRegisterComponentContext * Context=0x0000000000000000) Line 1963 C++ UE4Editor-UnrealEd-Win64-Debug.dll!UEditorEngine::Map_Load(const wchar_t * Str=0x00000241c3ab9fb2, FOutputDevice & Ar={...}) Line 2771 C++ UE4Editor-UnrealEd-Win64-Debug.dll!UEditorEngine::HandleMapCommand(const wchar_t * Str=0x00000241c3ab9fb2, FOutputDevice & Ar={...}, UWorld * InWorld=0x0000000000000000) Line 6148 C++ UE4Editor-UnrealEd-Win64-Debug.dll!UEditorEngine::Exec(UWorld * InWorld=0x0000000000000000, const wchar_t * Stream=0x00000241c3aba080, FOutputDevice & Ar={...}) Line 5705 C++ UE4Editor-UnrealEd-Win64-Debug.dll!UUnrealEdEngine::Exec(UWorld * InWorld=0x0000000000000000, const wchar_t * Stream=0x00000241c3aba080, FOutputDevice & Ar={...}) Line 697 C++ UE4Editor-UnrealEd-Win64-Debug.dll!FEditorFileUtils::LoadMap(const FString & InFilename={...}, bool LoadAsTemplate=false, const bool bShowProgress=true) Line 2554 C++
注1:在编辑器Preview模式下,打开地图时,World的bEnableTraceCollsion为true,ECollisionEnabled::NoCollision的物体也会创建物理对象
注2:PIE下,InitWorld时传入缺省的InitializationValues()参数,使得World的bEnableTraceCollsion为false,但由于此时存在2个World(Preview World和PIE World),在PVD中依然会显示ECollisionEnabled::NoCollision的物体
注3:Standalone下,打开地图时,InitWorld时传入缺省的InitializationValues()参数,使得World的bEnableTraceCollsion为false,ECollisionEnabled::NoCollision的物体不会创建物理对象
注意2
因此,要在Standalone模式下,使用PhysX Visual Debugger工具来查看对象的物理。
或者,在编辑器中打开的空场景,并PIE运行,然后open切换到目标地图,就可以用PhysX Visual Debugger工具来查看目标地图的物理了。
PhysX中函数的耗时情况
PhysX内存统计
PhysX中线程执行情况
对上图的后面时间段进行放大:
注意3
Physx Visual Debugger工具非常不稳定,容易发生崩溃。
在使用时,建议工具栏上点击Disconnect按钮停止采集,保存到pxd2文件后,再查看场景中的对象和性能相关的数据。
写pxd2文件
/** UnrealEngine\Engine\Source\Runtime\PhysicsCore\Private\PhysXSupportCore.cpp */ void PvdConnect(FString Host, bool bVisualization) { int32 Port = 5425; // TCP port to connect to, where PVD is listening uint32 Timeout = 1000; // timeout in milliseconds to wait for PVD to respond, consoles and remote PCs need a higher timeout. PxPvdInstrumentationFlags ConnectionFlags = bVisualization ? PxPvdInstrumentationFlag::eALL : (PxPvdInstrumentationFlag::ePROFILE | PxPvdInstrumentationFlag::eMEMORY); PxPvdTransport* transport = nullptr; if (Host == FString(TEXT("localfile"))) { FString PhysXProfilingPath = FPaths::ProfilingDir() + TEXT("PhysXProfiling"); if (!IFileManager::Get().DirectoryExists(*PhysXProfilingPath)) { IFileManager::Get().MakeDirectory(*PhysXProfilingPath, true); } FString PvdToSave = FString::Printf(TEXT("%s/PhysX_%s.pxd2"), *PhysXProfilingPath, *FDateTime::Now().ToString()); transport = PxDefaultPvdFileTransportCreate(TCHAR_TO_ANSI(*PvdToSave)); } else { transport = PxDefaultPvdSocketTransportCreate(TCHAR_TO_ANSI(*Host), Port, Timeout); } if (transport != nullptr) { GPhysXVisualDebugger->disconnect(); //make sure we're disconnected first GPhysXVisualDebugger->connect(*transport, ConnectionFlags); } // per scene properties (e.g. PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS) are // set on the PxPvdSceneClient in PhysScene.cpp, FPhysScene::InitPhysScene } #endif // WITH_PHYSX
pvd CONNECT localfile // 写pvd文件
pvd CONNECT NODEBUG localfile // 写pvd文件,仅用于profile和meomry,不绘制
pvd DISCONNECT // 断开与PVD的连接
PVD打开.pxd2文件提示: “the file is corrupted”
原因1:该.pxd2文件被其他进程占用着
原因2:使用老的pvd软件(如:3.2018.04.23896843),可下载3.2021.01.29532135版本来使用
https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/apireference/files/inherits.html