If your headset and controllers have no tracking when the game starts, you will never be able to the right Chaperone bounds once you do acquire tracking.
Steps to reproduce:
Cover the controllers and headset, or move them out of view of the lighthouses before launching the editor.
Create a pawn with a SteamVRChaperone component. Print the result of SteamVRChaperone->GetBounds on every tick.
Set the player to use this pawn.
Start a VR preview.
You should see it print out all zeros (and in the past I think I have even seen garbage data), which is fine. We don’t have tracking.
Now uncover or move the headset into view of the lighthouses. You continue getting all zeros instead of getting the chaperone bounds.
What happens is the code initializes the bounds at plugin startup and never updates them afterwards.
Here’s the problem: Chaperone bounds are only initialized once at plugin startup:
if ((VRChaperone != nullptr) && (ChaperoneErr == vr::VRInitError_None))
{
ChaperoneBounds = FChaperoneBounds(VRChaperone);
}
And the FChaperoneBounds constructor isn’t doing any error checking:
/** Chaperone Support */
struct FChaperoneBounds
{
/** Stores the bounds in SteamVR HMD space, for fast checking. These will need to be converted to Unreal HMD-calibrated space before being used in the world */
FBoundingQuad Bounds;
public:
FChaperoneBounds()
{}
FChaperoneBounds(vr::IVRChaperone* Chaperone)
: FChaperoneBounds()
{
vr::HmdQuad_t VRBounds;
Chaperone->GetPlayAreaRect(&VRBounds);
for (uint8 i = 0; i < 4; ++i)
{
const vr::HmdVector3_t Corner = VRBounds.vCorners[i];
Bounds.Corners[i] = RAW_STEAMVECTOR_TO_FVECTOR(Corner);
}
}
};
FChaperoneBounds ChaperoneBounds;
The problem is in this line:
Chaperone->GetPlayAreaRect(&VRBounds);
OpenVR’s GetPlayAreaRect returns a boolean of whether it was valid or not; UE4 isn’t error checking it. And it never gets called again after startup.
I have a patch to fix these issues, but it changes the blueprints interface a bit. Basically it adds a blueprint function to try to update the cached bounds. If GetPlayAreaRect(&VRBounds); returns false, the blueprint function returns false as well and leaves the previous bounds in place.
Additionally, SteamVRChaperone->GetBounds is updated to also return a boolean indicating if the bounds are valid.
Let me know if you guys agree this is a bug, and I can submit a pull request with my patch.
Thanks