c-frame / aframe-extras

Add-ons and helpers for A-Frame VR.
https://c-frame.github.io/aframe-extras/examples/
MIT License
967 stars 309 forks source link

add vertical movement to universal-controls #149

Closed rob-lindman closed 6 years ago

rob-lindman commented 7 years ago

wasd controls are useful with aframe on desktop.

what's missing is vertical movement with either pgup / pgdown or q / z or similar.

I tried universal-controls="fly: true" on the camera, but the flying is extremely fast, and seems to keep going, making it impossible to stabilize the camera at this point, and it influences the movement by allowing going 'forward straight up'

I am new to aframe so how exactly to go about this is non-obvious, but what I am seeking is vertical movement with the same speed and stability as the wasd controls. it does not need to go into a free look mode and launch into orbit. merely to move along the up-down axis with the same velocity.

I can see some other missing functionality here for a variety of use cases I will document later.

Also, the free look functionality of being able to look up and down was nice with ' universal-controls look-controls="enabled: true" ', but for my usage (in this instance) being able to move along 'ground axis' only without having the camera angle influence movement is what is desired. So if you look at a 20 degree angle upward and press W you still move forward on a flat plane.

Not sure if words best explain this, but basically, if you look at Quake 3, you can walk around using WASD and look around freely but when you look around you are still walking on the ground. Also Minecraft has a creator mode where page up and page down move your character up and down. In fact I would say Minecraft's flying behavior is a fantastic reference for the movement I am looking to provide in this use case.

donmccurdy commented 7 years ago

You can control the speed of universal-controls with:

<a-entity universal-controls="fly: true;
                 movementEasing: 15;
                 movementAcceleration: 80;"></a-entity>

Higher easing makes the camera slow down faster when you stop pressing a key, and higher acceleration makes it start up faster. The difference of those two determines max speed.

But to get dedicated buttons for moving up or down, I think you're going to need a new component plugged into universal-controls. Something like:

<a-entity qz-controls>
  <!-- or you could use universal-controls instead of both look- and wasd-controls. -->
  <a-entity camera="userHeight: 1.6" universal-controls="movementControls: qz-keyboard, hmd"></a-entity>
</a-entity>

Then you need to write the qz-keyboard-controls component. It could be a copy of keyboard-controls, you should just need to change a couple lines in getVelocityDelta().

AFRAME.registerComponent('qz-keyboard-controls', {
  // ...

  getVelocityDelta: function () {
    var data = this.data,
        keys = this.getKeys();

    this.dVelocity.set(0, 0, 0);
    if (data.enabled) {
      if (keys.KeyW || keys.ArrowUp)    { this.dVelocity.z -= 1; }
      if (keys.KeyA || keys.ArrowLeft)  { this.dVelocity.x -= 1; }
      if (keys.KeyS || keys.ArrowDown)  { this.dVelocity.z += 1; }
      if (keys.KeyD || keys.ArrowRight) { this.dVelocity.x += 1; }

      // NEW STUFF HERE
      if (keys.KeyQ)  { this.dVelocity.y += 1; }
      if (keys.KeyZ) { this.dVelocity.y -= 1; }
    }

    return this.dVelocity.clone();
  },

  // ...
});

Here is the table of possible keys: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code#Code_values

rob-lindman commented 7 years ago

this looks helpful, it's unclear to me exactly what to copy when it comes to the keyboard controls component. I went and looked at the repo and it seemed perhaps the built in component has other parts because it is part of a library or something, requiring other things... it might be helpful if there was some sort of a boilerplate (or perhaps the keyboard-controls in aframe extras is the boilerplate and I just don't get it (yet))...

donmccurdy commented 7 years ago

I would ignore the aframe-keyboard-controls repo, that's an older standalone thing that doesn't play well with universal-controls.

This is the file to use as a starting point: https://github.com/donmccurdy/aframe-extras/blob/master/src/controls/keyboard-controls.js#L53-L66, with two changes:

  1. Instead of module.exports = you will want AFRAME.registerComponent('qz-keyboard-controls', ... );
  2. For the require('../../lib/keyboard.polyfill'); thing at the top, you can delete that and it should still work in Chrome and Firefox. If you need other browsers you can just include this file somewhere on the page.
rob-lindman commented 7 years ago

thanks. yep, it was that stuff in the header that was confusing to me.

rob-lindman commented 7 years ago

apparently missing a parenthesis somewhere, or I added one in the wrong spot.

aframe-qz-keyboard.js.txt

rob-lindman commented 7 years ago

ok on the last line I apparently reversed the }). So I have this functional. The only issue is that it's too fast. on the ground plane it moves exactly as I'd like it. vertically, it just seems to go too quickly. I'll look back at your prior comments and see if I can figure this out.

rob-lindman commented 7 years ago

I am not sure if this detail is useful. I am still experiencing 'turbo mode' when going vertical. what I noticed is that each time I press either Q or Z with the above code I get a console message that says:

THREE.VRControls: .resetSensor() is now .resetPose().

Perhaps this is a change that is the reason why fly: true works strangely and why getting the vertical movement to stop does not work the same as horizontal movement.

It seems to have a steep acceleration curve when moving vertically and unlike horizontal movement when you let off the key it simply keeps going unless you hit the key to go in the opposite direction.

donmccurdy commented 7 years ago

Hmm I see. Your code looks right. The universal-controls component dampens horizontal movement but not vertical. See these lines. That will require a tweak to universal-controls. It's likely to be a several days before I can get to that unfortunately.

I have no idea what to make of the THREE.VRControls: .resetSensor() is now .resetPose(). message, but that shouldn't be affecting keyboard controls anyway. If there's a demo you could share I can (e.g. Codepen or Github Pages) I can look at that also.

rob-lindman commented 7 years ago

I will see about putting a demo together and I am cool with waiting a couple of days. Thanks for the indication of where this could be in the universal controls.

rob-lindman commented 7 years ago

Not sure if this helps, but while browsing aframe examples, I came across this page, which uses E and R keys to navigate up and down, and seems to do exactly what is needed (not going super fast, stopping on keyup).

https://aframe.argonjs.io/vuforia-aframe-logo/index.html

As I am just learning here I am not sure how they achieved this. I will look in more depth soon, and see if there's something obvious that makes it just click.

donmccurdy commented 7 years ago

I've updated universal-controls to support easing on the Y axis, but you have to opt-into it (otherwise things like physics break...). Example:

<a-entity camera="userHeight: 1.6" universal-controls="fly: true; movementEasingY: 15"></a-entity>
MilesMcBain commented 6 years ago

@donmccurdy when you say "things like physics break" do you mean physics applied to the entity that has the controls i.e. the player? So they wont fall correctly? That makes sense. But other entities should be fine?

donmccurdy commented 6 years ago

@MilesMcBain right, it should only affect the player. I forget if falling didn't work or you couldn't climb slopes or what exactly...

rob-lindman commented 6 years ago

I never had time to check back on this... My app is still weird because the acceleration increases. I just wanted movement on the 'veritical' axis to be basically the same as the 'ground plane'. has that been improved?

donmccurdy commented 6 years ago

Syntax has changed:

<a-entity id="rig"
          movement-controls="fly: true; easingY: 15"
          position="25 0 25">
  <a-entity camera
            position="0 1.6 0"
            look-controls="pointerLockEnabled: true"></a-entity>
</a-entity>

but it should be behaving as before.

rob-lindman commented 6 years ago

It's been a while since I touched my project, I will probably have to rewrite it to be current with library changes. I'll look at it when I can.

The behavior before was NOT what I wanted. Once you started moving up-down, you just kept accelerating, and it was almost impossible to get it to stop.

donmccurdy commented 6 years ago

That is what easingY is for, added earlier on in this thread. The higher it is, the faster vertical movement decelerates, which matches how horizontal movement is handled.

Demo: https://codepen.io/donmccurdy/pen/VxPKMy?editors=1010

That behavior seems to be fixed, so closing this issue.

donmccurdy commented 6 years ago

An upcoming release will not have easing/acceleration, but just a simple speed property that works whether fly is on or off. movement-controls="fly: true; speed: 0.3".

rob-lindman commented 6 years ago

ok. I will wait for that. I will likely have to rewrite a lot of the code to my app, because it has been a year, and I know that aframe is continuously being updated. This feature is somewhat critical to it. I also know that aframe isn't really intended for what I have in mind, but a thought that would be useful would be... somewhat hard to describe... basically, focusing the camera on an object, and using that as the centerpiece of focus, so the camera would be orbiting / zooming / focused on the object. For reference I am trying to replicate certain aspects of Second Life with AFrame, and the movement along with the camera stuff is really all that's missing (along with some geometries)....

donmccurdy commented 6 years ago

What I described above is released now, so the syntax would be:

<a-entity id="rig"
          movement-controls="fly: true; speed: 0.3"
          position="25 0 25">
  <a-entity camera
            position="0 1.6 0"
            look-controls="pointerLockEnabled: true"></a-entity>
</a-entity>

It sounds a bit like you're describing the behavior of THREE.OrbitControls, in which case these controls may be an alternative: https://github.com/tizzle/aframe-orbit-controls-component

c1p81 commented 6 years ago

Good morning i'm trying to replicate this instructions to move (pan) the camera in 3 axis I can move with asdw keys in 2 dimensions but i need new pair of keys to move on the third z-axis Can someone give me a detailed tutorial .... i'm a geologist, not a developer and i need this for an educational stereo viewer for aerial photos. Thanks

donmccurdy commented 6 years ago

@c1p81 if the code above is not doing what you need (it lets you move in all three dimensions, but not exactly in the way you describe) could you post more info to Stack Overflow, and include the code above as an example of what you've tried? I can't provide a detailed tutorial but I think you'll be able to get an answer.

c1p81 commented 6 years ago

thank you for the quick reply i have a test hosted in a server of University of Florence http://150.217.73.96/vr/aframe-master/examples/boilerplate/hello-world/ the model is made with Photoscan and a UAV drone over a landslide in Tuscany (Italy) it's a big model (>25 Mb) with s and d i can zoom, with i can move left and right....the question is...how i can move up and down with the keyboard keys?? Thanks again for your help and work

donmccurdy commented 6 years ago

@c1p81 it doesn't look like you are using aframe-extras in that example, or the code suggested above. Try adding this script after the aframe script:

<script src="//cdn.rawgit.com/donmccurdy/aframe-extras/v4.1.1/dist/aframe-extras.min.js"></script>

and then this HTML for the player/camera:

<a-entity id="rig"
          movement-controls="fly: true; speed: 0.3"
          position="25 0 25">
  <a-entity camera
            position="0 1.6 0"
            look-controls></a-entity>
</a-entity>

Like this: https://codepen.io/donmccurdy/pen/qYJpwe?editors=1010

You will be able to point the camera up and press W to "fly" up. But there is no special button to move up and down. If that is not what you want, you will need to post on Stack Overflow for help creating something else.

c1p81 commented 6 years ago

Works fine with the Daydream controller..very useful for geomorphology Thank you so much Luca

Emnolope commented 1 year ago

Not sure if this helps, but while browsing aframe examples, I came across this page, which uses E and R keys to navigate up and down, and seems to do exactly what is needed (not going super fast, stopping on keyup).

https://aframe.argonjs.io/vuforia-aframe-logo/index.html

As I am just learning here I am not sure how they achieved this. I will look in more depth soon, and see if there's something obvious that makes it just click.

They use an entirely different framework for handling the keys called argon.js. Hasn't been updated in years unfortunately.

turbotimon commented 1 year ago

Syntax has changed:

<a-entity id="rig"
          movement-controls="fly: true; easingY: 15"
          position="25 0 25">
  <a-entity camera
            position="0 1.6 0"
            look-controls="pointerLockEnabled: true"></a-entity>
</a-entity>

but it should be behaving as before.

Greetins from the future: This was extremely useful for me. However, syntax has changed again (refering a-frame v1.4.0), this should work. Docu for wasd-controls here.

<a-entity camera look-controls wasd-controls="acceleration:65; fly:true" position="0 1.6 0"></a-entity>
vincentfretin commented 1 year ago

wasd-controls is a component from aframe core. movement-controls is a component from aframe-extras. The previous code snippet is working with latest aframe-extras 7.0.0 but there is no easingY property, not sure what it did, we have a speed property.

turbotimon commented 1 year ago

Thanks for the clarification!