07-25-2021 09:27 AM
I'm working on a roomscale game that requires accurate incorporation of the guardian as well as tracking any changes immediately.
A while back I posted here about getting guardian updates and I got the suggestion to use focus change and other events. That was super helpful and worked well. However, I recently changed some code to make it more efficient and now I have a new problem. It seems that if I call OVRManager.boundary.GetGeometry(OVRBoundary.BoundaryType.PlayArea) immediately after I get focus back, I'll get the previous geometry and not the updated geometry. If I pause a bit, it works fine. There's some chance it is due to my code, but I think I've eliminated that as a possibility.
Is there any event/callback/whatever that fires when the guardian changes on a Quest? If not, any thoughts/suggestions/directions to investigate? I'm currently using a delay of a few frames, but that seems hokey and open to problems.
Thanks,
Damon
07-25-2021 01:12 PM
This is getting back into hack territory, but for the next few frames (seconds?) after getting input focus back you could use boundary.TestPoint to see if the shape of the guardian has changed. This way you could immediately respond when the change is detected. I don't know how expensive this call is, which is why I don't recommend checking it forever.
var result = OVRManager.boundary.TestPoint(Vector3.zero, OVRBoundary.BoundaryType.OuterBoundary);
if (result.ClosestPoint != previousClosestPoint) {
// boundary has changed size/shape
}
07-25-2021 01:26 PM
Interesting, thanks for the idea. It seems like there ought to be a much better built in solution. I'm going to hold out for that for a bit. If nothing comes I'll see if anything here will work better than my "wait a bit" solution. I can add yours into my wait a bit which already timesout quickly. And I'll also try to contact somebody at unity and see if they agree there should be a better solution. Roomscale games are awesome, but it feels like it is still pretty early days for true roomscale support.
09-01-2021 07:57 AM
Any chance you could share how you have been able to get GetGeometry to give you anything at all? I've been banging my head against this for a few days without success. And yes, I have run this call on Quest 2 directly and not just through Link. Thanks for any input!
09-01-2021 05:00 PM
This is probably not buildable, I pulled a bit from here and a bit from there, but hopefully it will give you the idea.
Feel free to ask any followups and good luck!!
Damon
Vector3 playAreaSize;
bool originReady = false;
bool configured = true;
bool done = false;
void CheckOriginMode()
{
TrackingOriginModeFlags tomFlags;
List<XRInputSubsystem> subsystems = new List<XRInputSubsystem>();
SubsystemManager.GetInstances<XRInputSubsystem>(subsystems);
if (subsystems.Count == 0)
{
return;
}
originReady = true;
for (int i = 0; i < subsystems.Count; i++)
{
subsystems[i].TrySetTrackingOriginMode(TrackingOriginModeFlags.Floor);
}
}
void GetPoints () {
configured = OVRManager.boundary.GetConfigured();
if (configured)
{
//Grab all the boundary points. Setting BoundaryType to OuterBoundary is necessary
boundaryPoints = OVRManager.boundary.GetGeometry(OVRBoundary.BoundaryType.PlayArea);
if (boundaryPoints == null || boundaryPoints.Length == 0)
{
return;
}
playAreaSize = OVRManager.boundary.GetDimensions(OVRBoundary.BoundaryType.PlayArea);
done = true;
}
}
void GetBoundary () {
CheckOriginMode ();
if ( !originReady ) {
return;
}
GetPoints ();
if ( done ) {
doWhatever ();
}
}
09-02-2021 05:34 AM
I just noticed the comment about OuterBoundary. That actually refers to a previous version. I use PlayArea now which returns the 4 points of the largest rectangle contained within the guardian. I switched to that because that was better for my game than dealing with the much larger set of points that comes from using OuterBoundary.