Branch:
Binary
Build Version:
4.7.0-2467323
Repro Steps:
- Create new blank project “LevelVolume” with no starter content
- Create new LevelStreamingVolume
- Position LevelStreamingVolume at 0,0,0
- Scale LevelStreamingVolume to 100000,100000,100000
- Create new sublevel level “SubLevel” in Levels window
- Add LevelStreamingVolume to “Streaming Volumes” property of “SubLevel” in “Level Details” window
- Open “Output Log” window
- Hit “Play” and don’t move mouse
- While not moving mouse, Move camera forward and back with “W” and “S” while still keeping ground in view
Result:
Notice that in output log you will see:
LogWorld: PIE: Copying PIE streaming level from /Game/SubLevel.SubLevel to /Game/UEDPIE_0_SubLevel.SubLevel. OwningWorld: /Temp/UEDPIE_0_Untitled_1.Untitled_1
LogWorld: PIE: Copying PIE streaming level from /Game/SubLevel.SubLevel to /Game/UEDPIE_0_SubLevel.SubLevel. OwningWorld: /Temp/UEDPIE_0_Untitled_1.Untitled_1
LogWorld: PIE: Copying PIE streaming level from /Game/SubLevel.SubLevel to /Game/UEDPIE_0_SubLevel.SubLevel. OwningWorld: /Temp/UEDPIE_0_Untitled_1.Untitled_1
LogWorld: PIE: Copying PIE streaming level from /Game/SubLevel.SubLevel to /Game/UEDPIE_0_SubLevel.SubLevel. OwningWorld: /Temp/UEDPIE_0_Untitled_1.Untitled_1
LogWorld: PIE: Copying PIE streaming level from /Game/SubLevel.SubLevel to /Game/UEDPIE_0_SubLevel.SubLevel. OwningWorld: /Temp/UEDPIE_0_Untitled_1.Untitled_1
LogWorld: PIE: Copying PIE streaming level from /Game/SubLevel.SubLevel to /Game/UEDPIE_0_SubLevel.SubLevel. OwningWorld: /Temp/UEDPIE_0_Untitled_1.Untitled_1
LogWorld: PIE: Copying PIE streaming level from /Game/SubLevel.SubLevel to /Game/UEDPIE_0_SubLevel.SubLevel. OwningWorld: /Temp/UEDPIE_0_Untitled_1.Untitled_1
LogWorld: PIE: Copying PIE streaming level from /Game/SubLevel.SubLevel to /Game/UEDPIE_0_SubLevel.SubLevel. OwningWorld: /Temp/UEDPIE_0_Untitled_1.Untitled_1
LogWorld: PIE: Copying PIE streaming level from /Game/SubLevel.SubLevel to /Game/UEDPIE_0_SubLevel.SubLevel. OwningWorld: /Temp/UEDPIE_0_Untitled_1.Untitled_1
Each one of those lines is “SubLevel” being reloaded. However this is not supposed to happen since player was always inside LevelStreamingVolume
Notes:
Making level streaming volume small will probabilistically avoid this issue. While size of level streaming volume that I need for my game is not as large as volume used for this bug report I am still occasionally experiencing sublevel reloads.
bug is easily seen when LevelStreamingVolume’s size is exaggerated and that is why it’s so large in this bug report.
I also explored Unreal’s source code to figure out why this problem was happening.
In commit: b613e1c103c971412e2a834f3c5f074f37875d99
I found that problem could be seen in:
Engine/Source/Runtime/Engine/Private/LevelTick.cpp line 597:
bViewpointInVolume = StreamingVolume->EncompassesPoint( ViewLocation );
variable “ViewLocation” is a 3D point and “EncompassesPoint” evaluates to false for certain values of “ViewLocation” even tho “ViewLocation” is encompassing “StreamingVolume”.
Following execution of “EncompassesPoint” I ended up at:
Engine/Source/Runtime/Engine/Private/PhysicsEngine/BodyInstance.cpp line 3592:
float SqrDistance = PxGeometryQuery::pointDistance(PPoint, PGeom, PGlobalPose, &PClosestPoint);
Call Stack:
UE4Editor-Engine-Win64-Debug.dll!FBodyInstance::GetDistanceToBody(const FVector & Point, FVector & OutPointOnBody) Line 3594 C++
UE4Editor-Engine-Win64-Debug.dll!UPrimitiveComponent::GetDistanceToCollision(const FVector & Point, FVector & ClosestPointOnCollision) Line 795 C++
UE4Editor-Engine-Win64-Debug.dll!AVolume::EncompassesPoint(FVector Point, float SphereRadius, float * OutDistanceToPoint) Line 63 C++
UE4Editor-Engine-Win64-Debug.dll!UWorld::ProcessLevelStreamingVolumes(FVector * OverrideViewLocation) Line 597 C++
function “pointDistance” is a PhysX function that is supposed to return 0 if “PPoint” is inside “PGeom”.
But “pointDistance” returns > 0 for some “PPoints” that are inside “PGeom”. Thus telling Unreal to unload level and then reload level once your character moves and “PPoint” changes.
Foot Note
That’s all I could find out about problem. I know that PhysX will be opening up their source code to Unreal Engine but in version I have I still don’t have access to PhysX’s source code. So I can’t keep digging inside “pointDistance” function.