Table of Contents
The BigWorld client uses a combination of Windows messages and the Windows raw input API for keyboard and mouse input. It reads key-up, key-down, and character press events from the keyboard as well as high resolution movement events from the mouse. It uses the DirectInput API to read button and axis movement events from joysticks.
Key events, encapsulated by the KeyEvent object
(BigWorld.KeyEvent
in Python), are generated by devices that
have keys or buttons. This includes the keyboard, mouse buttons, and
joystick buttons.
The two basic types of key events are key-down and key-up.
If a KeyEvent is generated by the keyboard, it may have a
character attached to it. The character generated by a particular key is
determined by the currently set locale and input language in the
operating system, and is represented by the
KeyEvent.character
member (a Unicode string).
Dead character keys are supported (e.g. in Spanish, a user can type the letter é by first pressing the apostrophe key followed by the e key). In this case the first key press will not have a character associated with it, and the second key press will have the final character.
The BigWorld client supports advanced Input Method Editors (IME). See Input Method Editors (IME) for details on using an IME in your game.
The keyboard will generate auto-repeat events when keys are held down, based on the user's operating system settings (e.g. repeat delay). The mouse and joystick do not generate auto-repeat events.
Auto-repeat events are sent as additional key-down events, however
scripts that do not want to handle repeat events can call the
KeyEvent.isRepeatedEvent
method to determine whther or not
it is an auto-repeat event.
When the user presses a button (keyboard, mouse or joystick), the sequence of events are:
-
The first key-down event.
-
If the key is held down, multiple key-down events are raised due to auto-repeat (keyboard only).
-
A key-up event is triggered when the user releases the button.
The output from the user input module is processed by a number of other modules, which take it in turn to examine events and either consume or ignore them. If an event is not consumed by any module then it is discarded. The order of modules that get a turn at the events is as follows:
-
Debug — Special keys, consoles, etc.
-
Personality script — Global keys.
-
Application — Hard-coded keys such as QUIT.
-
Player script — The rest, which is the major part of the processing.
Note
Note that the GUI system does not automatically receive input,
instead it is up to the script write to choose when. This could be
either in the personality script, or in the player script. The most
obvious place is in the personality script callbacks, for example in
the personality script's handleKeyEvent, you should call
GUI.handleKeyEvent()
and check the return value.
Similarly, the active camera also does not automatically receive input events. It is up to the Python scripts to decide when and where the camera receives user input.
The BigWorld client performs event matching to ensure consistent module behaviour. If a key-down event is consumed by a module, that module's identifier is recorded as the sink of the event's key number. When the corresponding auto-repeat and key-up event arrives, it is delivered directly to that module. For example, if a chat console is brought up (and inserted into the list) while the player is running, and the user subsequently releases the run key, then the player script will still get the key-up event for that key, and be able to stop the run action.
In some cases it may be desired to temporarily block certain key
events from being passed into the scripts. For example, the GUI scripts
may handle a key down event by removing the current GUI screen and
replacing it with a new GUI screen. By default, since the new GUI screen
has become the active screen by the time handleKeyEvent
returns, any associated auto-repeat and key-up events will be posted to
the new GUI screen creating possibly unwanted behaviour.
The BigWorld.sinkKeyEvents
function can be used to
stop all key events for the given key-code from reaching the scripts
until (and including) the next key-up. See the Python API guide for
details.
It is often a requirement to know where the mouse was when a key
event occured (i.e. rather than where the mouse is at the time of
handling the event), especially when processing mouse button events.
Therefore, the mouse cursor position is available via the
KeyEvent.cursorPosition
property, and should be used
instead of GUI.mcursor().position
where ever
possible.
High resolution mouse movement events are sent to the scripts as a
MouseEvent
. This object exposes three direction
deltas.
-
The
dx
anddy
members are signed integers indicating movement of the mouse in the X and Y directions. -
The
dz
member represents movement of the mouse wheel.Note
If multiple mouse deltas arrive from the driver within a single frame, they are accumulated into a single
MouseEvent
.
Similar to the KeyEvent
object, the mouse cursor
position for when the event occured is available as a member of the
MouseEvent
object.
Mouse buttons are sent as a KeyEvent
, however they do
not generate auto-repeat events. See Key events
for details.
The BigWorld client will automatically detect the first joystick device attached to the system, and is been designed to be used with dual-stick style joypads.
When axis events occur, they will be sent to the scripts as an
AxisEvent
object via the handleAxisEvent
personality script function.
Joystick buttons are sent as a KeyEvent
, however they
do not generate auto-repeat events. See Key events for details.
The C++ engine will automatically pass axis events to the active
cursor, so the direction cursor can be joystick controlled by setting it
as the active cursor using BigWorld.setCursor
. The
direction cursor will process any events generated by the right
axis.
The C++ engine will also give the physics subsystem a chance to handle axis events. The physics treats axis input as a special case and will scale movement speed by how far the user as pushed the joystick forward.
In order to enable joystick support on movement physics, set the
Physics.joystickEnabled
property to True and be sure to set
joystickFwdSpeed
and joystickBackSpeed
properties to values appropriate for your game.