# Creating Cockpit Interactions When it comes to creating cockpit interactions, we recommend making heavy use of the **core templates** that come supplied with the SDK. These can be found in the following folder that was installed with the SDK: <SDK\_ROOT>\(ModelBehaviorDefs\)Asobo\_EX1\\ You can also find versions of them that are simpler to study included in this documentation on the following page: - [Template Explorer](../../templateexplorer/template-explorer/)   When it comes to setting up the files for interactions, we recommend that you create a hierarchy, both with the model behavior files themselves and with the contents of the files. For example, looking at the Cabri G2 sample project (included with the SDK) you will see that all of the cockpit behavior XML is found in the `Function_Interior` attachment, and is split into several files: {{< image-center src="images/5_Content_Config/Models/behaviours/interactions/interaction_1_files.png" alt="The Cockpit Model Behavior Files Used By The Cabri G2" >}} {{< callout context="note" title="NOTE" icon="outline/bulb" >}} Due to aircraft in Microsoft Flight Simulator 2024 being [modular](../../../../modular-simobjects/modular-simobjects/) in nature, the placement of these files will depend greatly on how you wish to setup the common folder and the accompanying presets and attachments as well, since model behavior XML can be present in all of them. This page is only going to concentrate on how the model behavior files work together and not the actual file and folder hierarchy of the aircraft, although this will be something to keep in mind when creating your own XML. {{< /callout >}}   In this case the main model XML file (`cockpit.xml`) simply has the LOD info and then a `` element which uses `` to call another file, `cockpit_Behavior.xml`. It's *this* file which does most of the heavy lifting and contains the main components and also adds the other files (**core** templates and more custom files). This structure means that you have one file for the LODs, one file for the components, and then additional files for templates and parameter functions, making everything easier to not only debug, but extend and edit at a later date.   The rest of this page will describe the setup of cockpit interactions using the core model behavior templates that are supplied with the SDK, concentrating on the main supplementary XML file (ie: the one referenced from the main model XML file, as explained above). Before continuing we recommend that you check the following page which contains important details on component hierarchy and audio for cockpit components: - [Adding Sound To Interactions](adding-sound-to-interactions/)   You can find some more advanced techniques for using model behaviour templates on the following page, but you should make sure you understand and follow everything listed here first before going through these pages: - [Interaction Configurations](interaction-configurations/) - [Advanced Interactions](advanced-interactions/)   Finally, most interactions will require the a **tooltip** to be set up. How this is done is explained on the following page: - [Creating Interaction Tooltips](creating-interaction-tooltips/)     ### Initial File Setup The file that you'll be creating will not have any LOD data (since that will be handled by the main model XML file), and will only be used for creating interaction components. To start with in this file you will need the `` element at the top level, eg: ``` xml ```   You should then use the `` element to reference the **core** files that will contain the templates you'll need for the interactions to work: ``` xml ```   The file is simply an "index" file that then references other core templates, which in turn reference *other* template files. Using this file simply includes all the core templates you could possibly need when creating the interactions. The most important ones that will be included are: - [..\(Asobo_EX1\)Common\(Interior\)Utils\(Interactions\)Interaction\_Templates.xml](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-templates/) - [..\(Asobo_EX1\)Common\(Interior\)Templates\\Handling.xml](../../templateexplorer/asobo-ex1/common/interior/templates/handling/)   You *could* include only the files you need rather than all of them, but - unless you know *exactly* what you are doing - it is better to simply include all of them, as that gives you the most options and the least probability of errors.   The final thing to add to prepare your file is a core `` element that will initialise certain global parameters that will be required by the other templates you'll be using: ``` xml ```   Once you have this set up we recommend that you then "block out" the rest of the components you will require for the cockpit, as outlined on the page related to sound: - [Adding Sound To Interactions](adding-sound-to-interactions/)     ### Interaction Templates Once the location in the hierarchy has been decided for your files and the initial XML has been created to call the core templates, you will need to find which default interaction matches best with the instruments you aim to create an interaction for. This is obviously a subjective choice and will only affects the default properties of how your instrument will be interacted with. The main templates you will want to use are as follows:   {{< table-wrapper >}} | Template Name | Description | |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------| | [`ASOBO_CT_Simple_Interaction_Template` \[`ASOBO_IT_Simple_Interaction_Template`\]](../../TemplateExplorer/Asobo_EX1/Common/Shared/Utils/Interaction/Interaction_Templates.html#ASOBO_CT_Simple_Interaction_Template) | An interaction without animation | | [`ASOBO_CT_Button_Template` \[`ASOBO_CT_Button_Template`\]](../../TemplateExplorer/Asobo_EX1/Common/Shared/Utils/Interaction/Interaction_Templates.html#ASOBO_CT_Button_Template) | A button interaction | | [`ASOBO_CT_Switch_Template` \[`ASOBO_CT_Switch_Template`\]](../../TemplateExplorer/Asobo_EX1/Common/Shared/Utils/Interaction/Interaction_Templates.html#ASOBO_CT_Switch_Template) | A switch interaction | | [`ASOBO_CT_Lever_Template` \[`ASOBO_IT_Lever_Template`\]](../../TemplateExplorer/Asobo_EX1/Common/Shared/Utils/Interaction/Interaction_Templates.html#ASOBO_CT_Lever_Template) | A lever interaction | | [`ASOBO_CT_Knob_Template` \[`ASOBO_CT_Knob_Template`\]](../../TemplateExplorer/Asobo_EX1/Common/Shared/Utils/Interaction/Interaction_Templates.html#ASOBO_CT_Knob_Template) | A switch like interaction with a rotation animation | | [`ASOBO_CT_Knob_Finite_Template` \[`ASOBO_CT_Knob_Finite_Template`\]](../../TemplateExplorer/Asobo_EX1/Common/Shared/Utils/Interaction/Interaction_Templates.html#ASOBO_CT_Knob_Finite_Template) | A knob interaction with a min and max rotation | | [`ASOBO_CT_Knob_Infinite_Template` \[`ASOBO_CT_Knob_Infinite_Template`\]](../../TemplateExplorer/Asobo_EX1/Common/Shared/Utils/Interaction/Interaction_Templates.html#ASOBO_CT_Knob_Infinite_Template) | A knob interaction without any bounds for the rotation | | [`ASOBO_CT_Joystick_Template` \[`ASOBO_CT_Joystick_Template`\]](../../TemplateExplorer/Asobo_EX1/Common/Shared/Utils/Interaction/Interaction_Templates.html#ASOBO_CT_Joystick_Template) | A joystick interaction (for instance a two-axis trim controller on a yoke or a joystick that controls an avionics device) | | [`ASOBO_IT_HANDLING_Single_Yoke_Template` \[`ASOBO_IT_HANDLING_Stick_Template`, `ASOBO_IT_HANDLING_Single_Stick_Template`\]](../../TemplateExplorer/Asobo_EX1/Common/Interior/Templates/Handling.html#ASOBO_IT_HANDLING_Single_Yoke_Template) | A yoke or control stick animation | | [`ASOBO_IT_HANDLING_Double_Yoke_Template` \[`ASOBO_IT_HANDLING_Double_Stick_Template`\]](../../TemplateExplorer/Asobo_EX1/Common/Interior/Templates/Handling.html#ASOBO_IT_HANDLING_Double_Yoke_Template) | A yoke or control stick animation for dual cockpit | | [`ASOBO_IT_HANDLING_Single_Rudder_Pedals_Template` \[`ASOBO_IT_HANDLING_Rudder_Pedals_Template`\]](../../TemplateExplorer/Asobo_EX1/Common/Interior/Templates/Handling.html#ASOBO_IT_HANDLING_Single_Rudder_Pedals_Template) | Rudder animation for independent rudder pedals | | [`ASOBO_IT_HANDLING_Double_Helicraft_Rudder_Pedals_Template`](../../templateexplorer/asobo-ex1/common/interior/templates/handling/#ASOBO_IT_HANDLING_Double_Helicraft_Rudder_Pedals_Template) | Rudder animation for helicopters with dual cockpit | {{< /table-wrapper >}}   When using these templates it should be noted that in each interaction you will have an **axis**. The axis can be specified using the `` parameter, where: - {{< button "X" />}} means horizontal - `Y` means vertical For all templates the default axis is {{< button "X" />}} for knobs and `Y` for levers and switches, for example: ``` xml X ```   Additionally, there will be the following **common parameters** that each interaction template will understand and use:  
Parameter NameDescription
IN_BASE_NAMEHere you give the name of the node and animation in the model glTF. If they are different, you will instead need to specify <NODE_ID> and <ANIM_NAME> instead.
IE_NAMEHere you give the name of the input event created along with this interaction.
IE_TYPE

This is the input event category used for the interaction, which defaults to UNKNOWN if not included. Note this category has no direct effect on the simulation, but is used as a prefix to identify the input event for tooltip localisation (see here for more information), as well as in the debug display. It can be any of the following:

AUTOPILOT AUXILIARY DEICE ELECTRICAL ENGINE ROTOR FUEL HANDLING HYDRAULIC INSTRUMENT LANDING LIGHTING PNEUMATICS RADIO AUDIO SAFETY COMMON PROCEDURE VARIABLE UNKNOWN

IE_ID_SOURCEThis is used to provide and alternative prefix for tooltip localisation (see here for more information).
    ### Discrete State Interactions Some interactions expect to be given a set of discrete states corresponding to the different positions the instrument can take. The positions will be defined inside a ``, and in the component you'll use the `` parameter along with the name of the `` which defines the positions definition that you want to make use of, for example, using the [`ASOBO_CT_Switch_Template`](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-templates/#ASOBO_CT_Switch_Template) template: ``` xml OVHD_BELTS_SWITCH_FASTEN_1 FASTEN_BELTS MYFUNCTION_ON_AUTO_OFF_Settings 1 ```   The `` in this case can also go in the XML file, or - as the base MSFS 2024 aircraft do - it can go in a separate file that would be included with the package. This function will look like this: ``` xml ON AUTO OFF ```   This function uses one of the core templates, [`ASOBO_Auto_Define_Positions_And_Tooltips_Helper`](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-parametersfn/#ASOBO_Auto_Define_Positions_And_Tooltips_Helper). This is a helper function which defines positions based on the `POS_#` arguments with the expected syntax and a tooltip (see [Creating Interaction Tooltips](creating-interaction-tooltips/) for more information).   It is worth noting that the order of the positions is given by *axis*. If the switch moves on the **vertical axis**, then the positions should be listed from the **bottom to the top**. If the switch moves on the **horizontal axis**, then the positions should be listed from the **left to the right**.     #### Discreet State Position Configurations When using the [`ASOBO_Auto_Define_Positions_And_Tooltips_Helper`](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-parametersfn/#ASOBO_Auto_Define_Positions_And_Tooltips_Helper) there are some additional things to consider about how the positions will be used and how they can be manipulated for specific cases where the discreet states are not simple single clicks.   - ##### Position Animation Each position has a default animation position assigned to it. The value is expressed as a percent of the animation and will default to the position *index* (starting at 0) divided by the last position index multiplied by 100 (to convert it to percent). However you can override this default value by setting the parameter `POS_#_ANIM_PERCENT` where the value is the expected animation position in percent for the given position name (`#`).   - ##### Momentary Positions Some positions are meant to be "momentary", ie: when the switch is moved to that position it will then be switched to another position, after release, using some spring mechanism. For switches like this, you can use the parameter `POS_#_MOMENTARY_RELEASE_TARGET` where `#` is the name (index) of the position you want to make momentary. The value you supply the parameter is the position to "spring" to when the interaction is released. Here is an example: ``` xml NEUTRAL NEUTRAL CLOSE NEUTRAL OPEN ``` If you include the `POS_#_MOMENTARY_RELEASE_TARGET` parameter, you get access to other parameters that can further configure the momentary behavior: - **`POS_#_MOMENTARY_MIN_DURATION`** The minimum duration - in seconds - that this position will stay in the "momentary" state before springing back to the release target (if triggered externally, or using the `Inc`/`Dec` interaction events). Note that the default value is 0.75 but it can be changed for *all* positions by overriding the value of `DEFAULT_MOMENTARY_MIN_DURATION`. - **`POS_#_MOMENTARY_CONDITION`** This defines a condition that, when it resolves as "true", will enable the momentary behavior. Input condition can be something like a [SimVar](../../../../../programming-apis/simvars/simulation-variables/) or some [RPN](../../../../../programming-apis/reverse-polish-notation/).   - ##### Position Gates Most discrete state templates are **gated** by default, which means that you can't go from the *first* position to the *last* position in a single big movement: each state will block the input for a moment to avoid unintended position change (only *levers* work differently, as they don't have any gate by default). So, each position acts as a gate and can be configured as such using `POS_#_GATE_DIRECTION` with `#` being the position name (index) we want to add a gate to. The value of this parameter has to be one of the following: - `Both` - Gate will be blocking the interaction in both directions - `Inc` - Gate will be blocking the interaction when incrementing the position - `Dec` - Gate will be blocking the interaction when decrementing the position For example: ``` xml Both #CUR_ID# #LAST_STATE_INDEX# / 100 * near ```     ### Continuous State Interactions A continuous state is a control that moves smoothly from one position to another, like when you turn a knob or move a lever. Using the core templates, you can deal with this kind of interaction in two ways: as a **bounded continuous state**, or an **infinite continuous state**. The templates used for these two types of continuous interactions are very easy to use, as shown in the examples below.     #### Bound State Interaction The following is an example of a bound state continuous interaction for a **lever** using [`ASOBO_CT_Lever_Template`](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-templates/#ASOBO_CT_Lever_Template): ``` xml MAIN_PANEL_FOOT_AIR FOOT_AIR ``` The following is an example of a bound state continuous interaction for a **knob** using [`ASOBO_CT_Knob_Finite_Template`](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-templates/#ASOBO_CT_Knob_Finite_Template): ``` xml MAIN_PANEL_KNOB_LIGHT_AFDS_FLOOD_1 AFDS_FLOOD ASOBO_Glareshield_Light_Intensity_Settings_Config @LIGHTING_Light_Glareshield_AFDS ```     #### Infinite State Interaction The following is an example of an infinite state continuous interaction for a **knob** using [`ASOBO_CT_Knob_Infinite_Template`](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-templates/#ASOBO_CT_Knob_Infinite_Template): ``` xml GLSHD_MCP_KNOB_HEADING_SEL_1 HEADING_SEL ASOBO_FCC_Heading_Var_Config ```     ### Button Interactions Possibly the most common interaction in any cockpit will be the simple act of pressing a button. This is also one of the simplest interactions to set up, since they are only designed to send a single event and (at their simplest) only have one state (pressed/not pressed). In the following example we use the [`ASOBO_CT_Button_Template`](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-templates/#ASOBO_CT_Button_Template) where we specify what happens when the button is clicked - using `ON_EVENT` - and/or when the button is released - using `ON_RELEASE` (essentially a "stateless" button that simply does one thing when pressed and/or released): ``` xml FRNT_PUSH_AT_DISENGAGE_LIGHT AT_DISENGAGE 0 @Set_AT_Disengaged ``` This template also permits the following parameters, which can be useful when you require more control over the way the button is pressed or held: - `ON_LONG_PRESS_EVENT` - This parameter takes a snippet of RPN code which will be executed after a set time has passed since the button was pressed and held down. This time is defined using the `LONG_PRESS_DURATION` parameter. - `ON_BUTTON_HELD` - This parameter takes a snippet of RPN code which will be executed every frame, for as long as the button is held down.     #### Momentary State Buttons A **momentary state button** is one which has a different state depending on whether they are they are pushed or released, ie: for as long as the button is being held down then one state will be maintained, but releasing the button and it goes back to the initial state again. Test buttons usually have this behavior, for example: ``` xml OVHD_LE_DEVICES_PUSH_TEST_1 LE_DEVICES_TEST MYFUNCTION_Test_Settings ```     #### Toggleable State Buttons A **toggleable state button** is one which can be toggled between 2 or more discreet states. For example, if the button controls 3 states, then pressing the button once will change the state from 1 to 2, pressing again will go from 2 to 3 and then pressing again will go from 3 back to 1 again. For example: ``` xml OVHD_LE_DEVICES_PUSH_TEST_1 LE_DEVICES_TEST MYFUNCTION_Test_Settings_Toggles ``` Note that you can create a simple *two state toggle* by adding the <TOGGLEABLE/> and setting it to "true". This will then make the button act in the following way: - pressing the button toggles from an unpressed state to a pressed state and maintains the button "locked" in a pressed state. - pressing the button again, "unlocks" the button and it goes from a pressed state back to an unpressed state.     ### Simple Interactions In some cases, you will want to have an action happen without actually tying it to any particular animation. This is where *simple interactions* are useful, as they are exclusively designed to be used for interactions with no animations. For example in many Microsoft Flight Simulator 2024 aircraft there are invisible volumes which are used to toggle the visibility of the yoke: this would be considered a simple interaction, and uses the [`ASOBO_CT_Simple_Interaction_Template`](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-templates/#ASOBO_CT_Simple_Interaction_Template) template: ``` xml HANDLING_YOKE_HIDER_1_STATIC HIDER (>B:VARIABLE_YOKE_HIDDEN_Toggle) ```     ### Merged Interactions In many cases you will have items in the cockpit which require two or more simultaneous interaction events. For example, if you have a button tied to a knob or or a button tied to a lever. For these interactions the most important template it .   Some Interactions are merged together to make it simplify the interaction (ex: button on a knob or buttons tied to a lever). For these we use a parameter function called [`ASOBO_Add_Button_Helper`](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-parametersfn/#ASOBO_Add_Button_Helper), which will add a "button" interaction to any other interaction template that you use.   Here is a simple knob with a button example: ``` xml GLSHD_EFIS_KNOB_RANGE Range MYFUNCTION_Range_Settings TFC GLSHD_EFIS_PUSH_TFC MYFUNCTION_HIDDEN_Settings @TT_Package_Project.ACTION.EFIS_PUSH_TFC ``` {{< callout context="caution" title="IMPORTANT!" icon="outline/alert-triangle" >}} The `` "ID" attribute **must** be "Append\_With\_Button" otherwise the merged interaction will not work correctly. {{< /callout >}}     ### Covered Interactions In most cockpits there will be certain buttons or switches that have covers over them to prevent them being interacted with by accident. For these items you can create a special type of merged interaction that uses the [`ASOBO_Add_Cover_Helper`](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-parametersfn/#ASOBO_Add_Cover_Helper) template to add a cover that the user can flip up to be able to interact with the main button/switch, or flip down to prevent further interactions. For example: ``` xml OVHD_PASS_OXYGEN_SWITCH_MODE_1 PASS_OXYGEN OVHD_PASS_OXYGEN_SWITCH_MODE_COVER_1 ASOBO_ON_NORMAL_Settings NORMAL ``` {{< callout context="caution" title="IMPORTANT!" icon="outline/alert-triangle" >}} The `` "ID" attribute **must** be "Append\_With\_Cover" otherwise the merged interaction will not work correctly. {{< /callout >}}   It is worth noting that the only `` that you need to give is the `IN_BASE_NAME` for the cover. The input event will be defined *automatically* based on the interaction it covers, which will depend on the initial template (knob, button, switch). Also note that using the [`ASOBO_Add_Cover_Helper`](../../templateexplorer/asobo-ex1/common/shared/utils/interaction/interaction-parametersfn/#ASOBO_Add_Cover_Helper) template gives you access to an additional parameter: ``. This permits you to add in the state name to use as the "default" state that the knob/switch/button will be set to when the cover is closed.