Skip to content

Conversation

@KickSuch
Copy link

The movement-controls component requires the use of a camera "rig" wrapping the camera element. But you use room-scale VR setup, your movement in real life will change the X and Z position of the camera element. This will make camera not be centered in the rig, which creates issues with navmesh, because you are not where the rig thinks you are. For this problem I created 2 components.

  • room-scale-movement-stabilizer: stops camera movement, applied to a camera wrapper that is not the rig.
  • room-scale-movement-adjuster: simulates the movement from camera to the rig.

So when you need to have the camera centered in the rig, or need to restrict the camera movement even in room-scale VR, then instead of regular navigation mesh setup:

<a-entity id="rig" movement-controls="constrainToNavMesh: true">
  <a-entity camera
            position="0 1.6 0"
            look-controls="pointerLockEnabled: true">
  </a-entity>
</a-entity>

You will use:

<a-entity id="rig" 
          movement-controls="constrainToNavMesh: true"
          room-scale-movement-adjuster="constrainToNavMesh: true">
  <a-entity room-scale-movement-stabilizer>
    <a-entity camera
              position="0 1.6 0"
              look-controls="pointerLockEnabled: true">
    </a-entity>
  </a-entity>
</a-entity>

Along with the components this PR has README updates with the components' usage and example page that I used to debug this issue. You can try replacing the player in the example for the previous one and you will see how you can move outside of the navigation mesh.

@vincentfretin
Copy link
Member

Adding other components to fix the issue doesn't make sense to me. If there is a fix to do it should be directly in movement-controls tick, probably something similar to jure/aframe-blink-controls#27

@KickSuch
Copy link
Author

Adding 1 component is necessary if we want to have the camera stay above the player rig. We can not just take the X, Z position from the camera and reset the camera to 0 0, because the VR headset overrides the camera position with the room-scale position. Something like the room-scale-movement-stabilizer component on a camera wrapper entity is necessary to adjust the camera's position without editing the position of the camera entity.

But if we wanted just the navmesh clamping to take into consideration the camera's room-scale position, then we can do it without making new components. But this will not have the camera above the player rig which may confuse people thinking that the rig position is the player position when it in fact is the camera's world position.

Do you still think that not adding new components would be better?

@vincentfretin
Copy link
Member

Yeah I understand the player position is the camera's world position. We can adjust the camera rig position to offset the threejs camera position, that's what is done in the blink-controls PR. You shouldn't need an extra entity between the rig and camera.
Your room-scale-movement-adjuster component seems to do a similar thing than the movement-controls with the clamping, so that work is done twice and override each other setting the element position. It seems you're just lucky that the tick of your room-scale-movement-adjuster component is executed after movement-controls tick so that works.

@vincentfretin
Copy link
Member

Nevermind my comment about both components setting the position, it's actually on two different entities.
But yes I think it could be simplified just doing the logic in movement-controls tick unless there is really a thing I missed.

@KickSuch
Copy link
Author

I reverted the previous changes and made changes only to the movement-controls.

const velocity = this.velocity;

if (!velocityCtrl) return;
if (!velocityCtrl && !data.constrainToNavMesh) return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's probably wrong to add that condition here. The movement-controls still need to work with constrainToNavMesh=false

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part needs to stay. Without it the navmesh clamping is ignored until next movement input. It still works when the constrainToNavMesh=false, it only skips the tick if there is also no movement input. Alternatively we can remove this line entirely


if (data.constrainToNavMesh
&& velocityCtrl.isNavMeshConstrained !== false) {
&& (!velocityCtrl || velocityCtrl.isNavMeshConstrained !== false)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can revert that change if you revert the first change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first change must stay

cameraOffset.y = 0;

start.copy(el.object3D.position).add(cameraOffset);
if (velocityCtrl) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to check for velocityCtrl if you revert the first line change

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first change must stay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants