What pointer actions are there? Is it just the activate , as in the actual visible pointer? Or anything else?
It's just the visible pointer, yes.
At this point i've more or less decided to make an input rebinding wrapper. If i do this, i could add subaction information to every binding, for modders to use any way they wish. An example use case for this, could be to change which hand spells are cast from depending on which motion controller did the casting, since in this case the "Use" action would come with subaction information. Without subaction information, you would have to make two new actions, one for left and one for right, and expect the player to bind it correctly for every such use case (if there are any more).
There is a bigger issue with using them directly. I've ran into it when thinking about potential Steam Input API support. It's that we don't actually know how many bindings we need until runtime, since mods can add new bindings (aka input actions). Normally that's not an issue for games, so any such re-binding interfaces expect the list of bindings provided ahead of time, which is not possible in our case.
I'm not sure i understand, that sounds like another reason to create our own bindings wrapper. I'm guessing that's what you're saying?
That makes sense, except the `isMotionControllerActive` name is very confusing to me. I feel like the name should communicate that it's specifically "hand" controllers, or the left/right hand functions should mention `MotionController`.
I expect most people in the VR space will understand the MotionController terminology. You're right though that vr.isLeftHandActive() isn't as clear as i thought, it's not so obvious that it means the motion controller is on. vr.isLeftHandControllerEnabled() sounds more right. vr.isLeftHandMotionControllerEnabled() would be even clearer but I think it is more verbose than necessary.
I've used that terminology because you've presented two ways to "recenter".
I assume you are referring to the recenterZ parameter? The purpose of this parameter is for seated play, and implies whether the eye level should be adjusted or not. As i mentioned in my previous post, lumping this in with the recenter() call is probably a mistake. recenter() should just recenter XY, and adjusting the eye level should be a separate call.
Since i currently make no attempt at doing collision for the camera, recenter() is only automatically called on startup, load game, and instant transition (entrances, recall, interventions, and similar). Instant transitions imo should not automatically adjust eye level as it would cause the eye level to change around arbitrarily as the player is playing, which might be noticeable and annoying. Therefore instant transition currently calls recenter with recenterZ=false. While all other calls to recenter calls it with recenterZ=true. I think it would be less confusing if adjusting the eye level was instead a separate call, something like resetEyeLevel(). This would also allow the use case of resetting eye level separately, e.g. during/following the race select dialogue.
Whatever we call it, there might be other meaningful ways to normalize the VR camera offset, e. g. do it automatically somehow.
I know skyrim just automatically recenters you if your head gets too far from your character, e.g. by walking into a wall. That just means the VR code is making a call to recenter whenever that condition occurs. I'm not sure what the confusion about terminology is here?
Code: Select all
It's common for VR games to do something like that when the VR camera collides with a wall.
Isn't that just collision? Not letting the camera move if it would be moving through the wall. Using the term "recenter" for this wouldn't make any sense since that's not at all what would be happening.
Would it not be easier to just have two different bindings, left hand and right hand activate, and enable the right laser that way.
You quoted vr.isLeftHandedMode(), but I think you're rather arguing against the necessity for subactions? GUI mode still needs leftHandedMode to inform it which hand should be pointing. I'm not gonna force the user to hold down the pointer action while navigating menus. Or make it a lightshow of dual wielding lasers. leftHandedMode() also has the future use case of switching what hands are holding the weapon, shield, and drawing the bow string (if i ever implement realistic archery).
It would also allow bindings the left hand laser to right hand button, and vice versa, in case somebody prefers that.
Enabling the pointer on one hand and having it appear in another seems like an awkward experience. I wouldn't want to actively prevent it if someone really wants that, but it's specific enough that I think they could mod it themselves by flipping the pointing hands in the script.
I'm also fairly clueless about animations, and I'm not sure I understand exactly what you mean
I'm sure i'm doing a very poor job explaining it too. The Marionette and Attachment types that i'm talking about here do not currently exist, they are suggestings for an API for animation overriding.
"Marionette" is just what i'm naming a type that holds a collection of "Attachment" objects, and collectively binds/unbinds them to an actor. This is so that VR scripts don't have to manage a varying number of Attachment objects based on what tracking is available or not.
The "Attachment" type is an object that attaches to an actor and overrides a specific bone. The StaticAttachment type is an instance of Attachment available to Lua that exists to do specific, pre-scripted changes to animations, such as forcing a finger to point forward.
vr.playerMarionette() offers an instance of Marionette that contains all Attachments generated by tracking data from the player. These are instances of Attachment that are not available to Lua, since they need to under-the-hood update their tracking data at the right time and then apply to the bones, which can't be done via Lua. The alternative would be something like vr.getPlayerTrackers() which returns a list of Attachments directly instead of wrapping them inside the possibly confusing Marionette type.