A manipulation is an action the user can take by clicking on your object. Manipulations can only be used in cockpit objects.
Traditionally, manipulators have been focused on the interaction between the mouse and cockpit. VR implementation has added a few new possibilities and made older processes obsolete. This guide explains manipulators in terms of how real objects move instead of in terms of mouse clicks.
The Pieces Of A Cockpit Control
There are 6 components of a cockpit control.
- An interaction spot, such as a single place to click or interact in VR, or the two spots that are automatically created using something like Command Switch Up Down
- The manipulator type that tells X-Plane what type of interaction spot to make and what happens when you interact with it.
- The manipulator’s dataref or command, from X-Plane or a plugin, that changes or triggers when the interaction spot is interacted with. Also, certain other case by case parameters like cursor type, tooltip, etc
- The manipulator mesh, which determines where the interaction spot will be in X-Plane. It is usually blocky in shape for an easier time interacting with it
- A visual mesh for what the user sees. The manipulator mesh is made invisible (but is still interactable), while the user sees a high-detail visual mesh. This is standard for yokes, but may be more work than needed for simple buttons.
- Finally, the animations that keep the manipulator mesh and visual mesh (if you have any), moving in sync so it doesn’t break realism. This does not have to be the same as the manipulator dataref (if any), but very well could be.
A simple example: Making an extremely simple Push button (manipulator type) to fire commands.
- Make a panel where the button is supposed to be (interaction spot), and give the panel the relevant manipulator information, such as the command you want to use and the cursor to see.
- Finally, include the button in the cockpit texture so the user has something to look at.
A more complex example: Creating a slide for some trim flaps.
- You want a linear dragging motion, and pick Drag Axis for their manipulator type.
- Model the control, a small tapered cylindrical knob.
- Users say this is hard to click and easy to miss (interaction spot), so you make two meshes: One a slightly oversized cylinder that the user will actually click (manipulator mesh) and a high detail tapered cylinder the user will see moving (visual mesh).
- The manipulator changes the dataref sim/cockpit2/….trim (manipulator’s dataref).
- Since the user drags the manipulator mesh but sees small tapered visual mesh, they must be animated the same way. For convenience, the manipulator’s dataref is used.
And so, the user drags the trim flap slider up, the trim flaps go up, the animation moves up. Note: Clamping the manipulator’s animation is possibly essential to prevent incorrect or unrealistic motion
The following names are based on the OBJ spec and the XPlane2Blender add on. The names are probably similar in whatever OBJ exporter you are using. Otherwise, see the supporting documents of that exporter or e-mail their author for more details.
|MECHANISM You want||For firing commands||For changing DREFs|
|Interaction Is Consumed But Nothing happens||Noop||Noop|
|linear lever||Command Axis*||Drag Axis|
|With Detents||Drag Axis With Detents|
|rotational lever||Drag Rotate|
|With Detents||Drag Rotate With Detents|
|Ball Joint||Drag XY**|
*The command axis manipulator runs a command based on a drag in one direction and the other – this doesn’t fit well with real linear mechanisms, but in rare cases it can provide a nice user experience for a detented linear lever, like a flap handle.
** Ball joints do not work well in VR – the XY manipulator is an approximation
*** Yokes should be done via the XY manipulator – the _vrconfig.txt file has special commands
to make yokes work perfectly. See the VR configuration file format spec for details.
Details on Noop
If you want a click to be consumed before it reaches another manipulator underneath it, use a Noop. This is useful for temporarily disabling a control without the use of a plugin, such as a locked lid over an “EJECT” button. Make the glass a noop, and the button a Command. When the locked lid over and eject button has played its animation to raise, the eject button becomes clickable.
|push-button||Command||Push (radio, delta, toggle, wrap)|
|knob||Command Knob||Axis Knob|
|knob (2-way)||Command Knob 2|
|horizontal switch||Command Switch Left Right||Axis Switch Left Right|
|horizontal switch (2-way)||Command Switch Left Right 2|
|vertical switch||Command Switch Up Down||Axis Switch Up-Down|
|vertical switch (2-way)||Command Switch Up Down 2|
Note that the command variant is always preferred in terms of quality of user experience – dataref variants are provided only to help authors with weird situations. The various push button dataref manipulators vary based on what values are written to the dataref.
The Manipulation section of the OBJ8 spec contains more information about how these type names get turned into OBJ directives and the exact details of their parameters.