HSL Input System and Keybindings
- See also: Keybindings
Please Note: If you are simply looking for an easy way to reassign current key bindings in the HeroCloud, the GameKeyBindings.ini is provided in the root directory. It is in the GAME package and so may be freely edited to provide game-specific overrides.
The system described herein we will collectively call the "InputSystem", which is comprised of elements of C-level engine code, HSL client-side scripts and HSL server-side scripts. In general, this system is engaged only while HeroBlade or the client are in "game" mode. This means that the input that GUI elements receive and input that [HeroBlade interprets directly in edit mode are not handled by the "InputSystem" with the only exception being HeroicMouseEvents ( left/right click while in edit mode DOES result in a call to the Input_Mouse script's HeroicMouseDown and HeroicMouseUp functions ).
Commands are organized into logical groups called Command Layers, which in turn are pushed onto the Command Layer Stack. An incoming command sent to each Command Layer in the stack starting at the layer last pushed onto the stack until a layer indicates that it has processed the input by returning true or all layers have been given a chance to process the command. Command Layers that are currently on the stack may be selectively activated and deactivated.
Layers are pushed onto the stack during the login process as the result of a call to the client script CharacterSystem:OnSetControlledCharacter() using the external PushCmdLayer() function. Please note, because commands are passed through the stack of command layers the order of layers may be extremely important as one layer marking the command as "handled" will result in layers deeper in the stack never getting a chance to act on the command.
After Command Layers are pushed on the Command Layer Stack they must be activated using the external ActivateCmdLayer( layerName, true ). Deactivating a Command Layer uses the same function but sends the second parameter as false.
Popping the last command layer off the stack is a simple call to the external function PopCmdLayer(). However, in most cases popping the last command layer is probably never the right answer unless you know no other layer has been pushed onto the stack. More commonly you are likely to use the ActivateCmdLayer function to deactivate a command layer that is not currently being used.
Layers are defined first in the HeroEngineKeyBindings.ini file. They can also be defined in a second game-specific file, set as a client configuration parameter. A part of that definition is the script commands sent to that layer when the buttons are pressed. To use a new Layer, it must be first defined in the game-specific keybindings file before keybindings may be saved to the layer.
As of the HeroEngine 1.7.0, the following layers are defined:
|HE_Movement||_Input_Movement||Handles both mouse and keyboard movement commands|
|HE_Camera||_Input_Camera||Handles both mouse and keyboard control of the camera|
|HE_Command||_Input_Command||Handles keyboard commands for game controls such as activating abilities on a hotbar or opening GUIs such as inventory|
|HE_Mouse||_Input_Mouse||Maps the mouse buttons to input commands|
|GUIEditor||_Input_GUIEditor||Handles keyboard commands for manipulating elements in the GUIEditor mode|
Inputs such as a keypress or mouse-click are routed to the functions
OnCmdStop(), and for mouse movement
OnMouseMove() in the script specified by the layer's definition with the cmd set to the string that has been defined for the particular keycombination for that layer. Each of those functions returns a boolean, if the return value is true no further layers will be called for the current input event. Most layers return false for most commands as handling in the camera layer should not necessarily stop handling by the command layer.
|This is a Clean Engine file, any changes you make to it will be overwritten during the publish process.|
This file represents the default control scheme for the client, it is always active beneath the currently loaded keybinding profile (if any) and handles any input event keybinding profile does not override. The file is located in the root directory of your asset repository (HE/).
Displayed below is the representation of two of the Command Layers in the HeroEngineKeyBindings.ini.
Please Note: The Master Control is a HeroEngine Source Tool only and not needed when developing in the HeroCloud
Implementing your game specific keybindings file is as simple as setting a client configuration value in Master Control to provide the path to your game specific keybindings.ini file. As of June 5, 2010, GameKeyBindings.ini is provided also in the root directory. It is in the GAME package and so may be freely edited to provide game-specific overrides.
// DefaultKeyBindings.ini // // format: // // [LayerName] = ClientScriptName // Command = [CTRL+ | ALT+ | SHIFT+]Key // Command = UNASSIGNED // Command // // If UNASSIGNED is specified, the command will appear in the list returned // by GetKeyBindings(), and players can assign keys to it via SetKeyBinding(). // // If there is no equals sign, it will not appear in GetKeyBindings(), but scripts // can still call GetCmdState and SetCmdState on it. // // Combinations of modifiers such as CTRL+SHIFT are not supported. // // Commands are strings interpreted by the script. // //////////////////////////////////////////////////////////////////////////// // // List of all key names: // // MOUSE.LEFT // MOUSE.RIGHT // MOUSE.MIDDLE // MOUSE.4 // MOUSE.5 // A-Z // 0-9 (on main keyboard area) // NUM0-NUM9 (on the numeric keypad if numlock is engaged) // NUM/ (on the numeric keypad) // NUM* // NUM- // NUM+ // NUM. // NUMLOCK // CLEAR (num5 if numlock is not engaged) // F1-F12 // ` (accent/tilde) // - // = // [ // ] // \ (backslash) // / // ' (singlequote) // ; // , // . // TAB // INSERT // DELETE // BACKSPACE // CAPSLOCK // UP // DOWN // LEFT // RIGHT // HOME // END // PAGEUP // PAGEDOWN // SPACE // ENTER // ESC // // GAMEPAD.START // GAMEPAD.BACK // GAMEPAD.LEFTTHUMB // GAMEPAD.RIGHTTHUMB // GAMEPAD.LEFTSHOULDER // GAMEPAD.RIGHTSHOULDER // GAMEPAD.A // GAMEPAD.B // GAMEPAD.X // GAMEPAD.Y // GAMEPAD.DPADUP // GAMEPAD.DPADDOWN // GAMEPAD.DPADLEFT // GAMEPAD.DPADRIGHT // //////////////////////////////////////////////////////////////////////////// [HE_Movement] = _Input_Movement LeaveGameMode = CTRL+` Forward = ANY+W Forward = ANY+UP AutoForward = ANY+BACKSPACE AutoForwardEngaged Walk = CTRL Sprint = SHIFT Backward = ANY+S Backward = ANY+DOWN Left = ANY+A Left = ANY+LEFT Right = ANY+D Right = ANY+RIGHT RotateLeft = ANY+Q RotateRight = ANY+E ToggleToolTips = CTRL+T LeftButton = ANY+MOUSE.LEFT RightButton = ANY+MOUSE.RIGHT MouseMovementEngaged Jump = ANY+SPACE Jump = GAMEPAD.RIGHTSHOULDER JumpingEngaged [HE_Camera] = _Input_Camera DragRotate = ANY+MOUSE.RIGHT DragRotateCamera = ANY+MOUSE.4 DragRotateCameraEngaged ClearRotateCamera = ANY+MOUSE.5 ToggleFullscreen = F12 Click = MOUSE.LEFT ToggleAspectRatio = SHIFT+F12 RotateCameraUp = ANY+R RotateCameraDown = ANY+F ZoomIn = NUM+ ZoomOut = NUM- [HE_Command] = _Input_Command PlayMode = CTRL+G LeaveGameMode = SHIFT+` [HE_Mouse] = _Input_Mouse LeftButton = MOUSE.LEFT RightButton = MOUSE.RIGHT MiddleButton = MOUSE.MIDDLE DragSelectButton = CTRL+MOUSE.LEFT [GUIEditor] = _Input_GUIEditor DeleteControl = DELETE CopyControl = CTRL+C CutControl = CTRL+X PasteControl = CTRL+V MoveLeftGrid = LEFT MoveRightGrid = RIGHT MoveUpGrid = UP MoveDownGrid = DOWN MoveLeft = CTRL+LEFT MoveRight = CTRL+RIGHT MoveUp = CTRL+UP MoveDown = CTRL+DOWN ResizeLeft = SHIFT+LEFT ResizeRight = SHIFT+RIGHT ResizeUp = SHIFT+UP SelectParent = ESC ResizeDown = SHIFT+DOWN
Input scripts are called in turn based on the order in which their command layers were pushed onto the stack ( FIFO ). If an input script returns true to the function call, any further calls to the scripts of layers higher up in the stack will be prevented. Consequently, returning false is the standard unless you really don't want other layers to have the opportunity to execute from a particular input.
When an input is caught by the C engine, if a layer has that input it is then translated into the corresponding command and send to the input script for that layer. This means each layer is able to define a command for a particular input independant of what any other layer may have defined that input to be. For example,
ANY+MOUSE.RIGHT is defined as
DragRotate in the camera layer and as
RightButton in the Movement layer.
There are several functions that are called by the C engine:
|onCmdStart||Called when an input starts, such as pressing the key down.|
|onCmdStop||Called when an input stops, such as when a key is released.|
|onMouseMove||Called when the mouse's pointer is changing position.|
|onMouseWheel||Called when the mouse wheel is moved.|
|OnMouseEnter||Called when the mouse pointer enters a node which is MouseTargetable and not MouseTransparent.|
|OnMouseLeave||Called when the mouse pointer leaves a node which is MouseTargetable and not MouseTransparent.|
|OnMouseClick||Called when a mouse clicks on a node that is MouseTargetable and not MouseTransparent.|
|OnMouseDoubleClick||Called when a mouse double clicks on a node that is MouseTargetable and not MouseTransparent.|