aframe-teleport-controls
aframe-teleport-controls copied to clipboard
How to set orientation based on axis position after teleport?
from @machenmusik https://github.com/fernandojsg/aframe-input-mapping-component/issues
A common teleport mechanic now (robo recall, blade runner 2049, windows mixed reality) is for orientation after teleport to be set via axis position, and shown live while targeting. How should that best be done with teleport-controls?
This does serve to point out a common usecase that input-mappings currently does not map well onto, bindings that combine multiple types of inputs/events.
In order to do this behavior you would need a mapping to start teleport, a mapping for axismove, and a mapping to end teleporting. The teleport-controls component would need to store state about the axismove events and then use them in the teleport end event (similar to what is being done here for dpad controls https://github.com/mozilla/mr-social-client/blob/master/src/components/axis-dpad.js)
Not sure about the right way to solve this, but a non-evented way to access mappings would solve the intermediate state for these cases. Not sure what the mapping side would look like but I could imagine an api like AFRAME.input.getAxis("some_named_axis")
returning a float between -1 and 1, and AFRAME.input.getButtonDown("some_named_button") returning a boolean. Then in teleport-controls
tick` you could just query the current axis values to render the teleport target with facing information.
It can be a separate component that is looking for the right events, as long as teleport-controls provides the right ones. Not hard to have a component remember last trackpadmoved
or thumbstickmoved
and react to a teleport?
Or, you can just read the current values off the controller reference, right?
Based on https://github.com/fernandojsg/aframe-input-mapping-component/issues/12 what do you think about something like:
{
"trackpaddown": "startTeleport",
"axisMove[@state=startTeleport]": "rotateForwardVector",
"trackpadup": "endTeleport"
}
So on trackpaddown
the ray will appear, then you could decide depending on your controller if define the rotatingForward
that will be called just if the startTeleport
state is set and it will be called on axisMove
so in the listener we could get the Z
angle to modify the forward direction. Once we release the trackpad it will jump to that position.
Other option is to create another inputMapping
while you're on aiming/startTeleport
, maybe more verbose, but:
teleport: {
"trackpaddown": "startTeleport",
},
aiming: {
axisMove: 'rotatingForward',
"trackpadup": "endTeleport"
}
This is highly related to the latest comments by @johnshaughnessy on https://github.com/fernandojsg/aframe-input-mapping-component/issues/2
I don’t think creating a DSL where we have to parse strings and handle errors is a maintainable path. If a robo recall teleport system is something we need or someone is trying to implement right we can look into it, better with some working code. I would not anticipate too much, keep the input mapping simple and evolve it as we need.
Yep, the more I check the syntax with custom attributes and so on, the less I like it. It's a complex problem, I'm not sure how they solve it on the steam controller API. I believe @johnshaughnessy mentioned the modifiers or layers that could be used for that.
If we're painting and click the teleport it maybe makes sense to change the mapping to teleporting-state as you won't be able to do any other action while waiting for teleport.
So when the startTeleport
event is triggered, we set the state to teleportAiming
and on the teleport
event, we change it back to painting.
{
painting: {
vive: {
"triggerdown": "paint"
"trackpaddown": "startTeleport"
}
},
teleportAiming: {
vive: {
"trackpadup": "teleport"
"axismoveZ": "changeTeleportOrientation"
}
}
}
For this specific issue I believe this is enough to solve it but modifiers are something that we'll need. I'll open a specific issue on the input mapping for that.
Yes, I think teleportAiming involves a sate change. I propose two ideas to explore in the future but I do not love either of them yet 😄
-
tasks
\states
to be able to reuse othertasks
\states
. So you have to only define the differences in the mapping.
{
painting: {
vive: {
"gripdown" : "undo",
"menudown" : "togglepalette",
"triggerdown": "paint",
"trackpaddown": "startTeleport"
}
},
teleportAiming: {
use: 'painting'
vive: {
"trackpadup": "teleport"
"axismoveZ": "changeTeleportOrientation"
}
}
}
Another option is to allow for nested mappings:
painting: {
vive: {
"gripdown" : "undo",
"menudown" : "togglepalette",
"triggerdown": "paint",
"trackpaddown": "startTeleport"
},
mappings: {
teleportAiming: {
vive: {
"trackpadup": "teleport"
"axismoveZ": "changeTeleportOrientation"
}
}
}