control(key id, integer held, integer change)
Once a
script has
permission to take control inputs from the
avatar with the
key id (see
llRequestPermissions), and has taken control of the desired set (see
llTakeControls), this
event will be used to pass the
state of taken controls to the script.
The
held parameter is a
bitfield indicating which controls are held down. The
change parameter is a
bitfield indicating which controls changed their state since the last
control event. The combination of these two parameters can be used to determine the various states of any taken controls. The easiest way to do this is by comparing the parameters to pre-defined control
constants.
Here are the available control constants:
Constant name | Value | Hex Value | Description |
CONTROL_FWD | 1 | 0x00000001 | Tests for avatar forward control |
CONTROL_BACK | 2 | 0x00000002 | Tests for avatar back control |
CONTROL_LEFT | 4 | 0x00000004 | Tests for avatar move left control |
CONTROL_RIGHT | 8 | 0x00000008 | Tests for avatar move right control |
CONTROL_UP | 16 | 0x00000010 | Tests for avatar up control |
CONTROL_DOWN | 32 | 0x00000020 | Tests for avatar down control |
? | 64 | 0x00000040 | ? |
? | 128 | 0x00000080 | ? |
CONTROL_ROT_LEFT | 256 | 0x00000100 | Tests for avatar rotate left control |
CONTROL_ROT_RIGHT | 512 | 0x00000200 | Tests for avatar rotate right control |
CONTROL_LBUTTON | 268435456 | 0x10000000 | Tests for avatar left button control |
CONTROL_ML_LBUTTON | 1073741824 | 0x40000000 | Tests for avatar left button control with the avatar in mouselook |
The
held and
change parameters can each have information on multiple controls in any received event. If a control is pressed down the corresponding bit (matching the control
constant) in the
held parameter will be set to 1. If the state of the control just changed from up to down or down to up, the corresponding bit in the
change parameter will be set to 1.
Since we tend to think more of presses, holds and releases, it's useful to know how they relate. If the bit for a given control is unset (0) in both parameters then it hasn't been touched and it is up. If the bit in both the
held and
change parameters is set (1), then the control was just pressed. If
held is set and
change is not, then the button is being held down. As long as the button is held down additional control events will be generated with the control's
held bit set. If the
held bit is unset and the
change bit is set, then the control was just released.
So if a '1' indicates the presence of the desired control constant in the parameters (across the top) for each control state (down the side) then:
| held | change |
button not held | 0 | 0 |
button press | 1 | 1 |
button held down | 1 | 0 |
button release | 0 | 1 |
Detecting Controls
There are a few ways you can test for controls in your code. Remembering your
bitwise operators you'll note that
& is the intersection. So only bits that are set on both sides of the operator will remain set in the result. This is handy for seeing if the same bit is set in two values.
Or (the 'pipe' operator
|) is the union. All bits set in both arguments are set in the result. This can be useful for combining control constants to check for combinations. Be careful though, checking for multiple bits is tricky (see below).
The following code looks for an initial press of the
forward button by and'ing
held and
change (if it's held and changed that's a press) and the desired control constant. Since only a single bit representing
forward is set in the
CONTROL_FWD constant, and'ing that constant with the two parameters will only result in a
TRUE value if that bit is also set in both the
held and
change parameters (i.e. the button was pressed).
if (held & change & CONTROL_FWD) llOwnerSay("forward pressed");
This code looks for a button release:
if (~held & change & CONTROL_FWD) llOwnerSay("forward released");
The ~ operator is
bitwise NOT, i.e. it flips all the bits from 0 to 1 or 1 to 0. If the
CONTROL_FWD bit is set in
~held it was unset in the original
held, which means it is
up (not depressed).
This code looks for a button being held down (and will include the initial press since it's true then as well):
if (held & CONTROL_FWD) llOwnerSay("forward held");
An alternative style that might be easier for some to understand maps more directly to the control state table above and looks like so:
if ((held & CONTROL_LBUTTON) && (change & CONTROL_LBUTTON)) llOwnerSay("mouse press");
if ((~held & CONTROL_LBUTTON) && (change & CONTROL_LBUTTON)) llOwnerSay("mouse release");
If there's a 0 in the row you want for one of the parameters put a tilde ~ in front of it in the if statement. If it's a 1, leave it normal.
Handling Multiple Controls
A single callback to this function can contain information on the status of multiple controls so they can be combined for more detailed actions. This is tricky because you may want to insure that all the bits you're looking for are set if you're looking for a "combo" move of more than one key. A statement like the following won't work as expected:
if (held & change & (CONTROL_FWD | CONTROL_LEFT)) llOwnerSay("forward and/or left"); // Might not be what you want!
The problem is a case where only one of the specified controls is pressed, the
forward button for example. Looking at the table at the top,
forward has a value of 1.
Left has a value of 4 (100 binary). So
CONTROL_FWD | CONTROL_LEFT has a value of 5 (101 binary). If the
forward key is pressed alone, both
held and
change will have a value of 1. In this case
1 & 1 & 101 evaluates to 1 because the first bit (1) is set in all 3 arguments and since one is
TRUE the combo will be detected.
This is fine if you are looking for any combination of the specified controls, but if you want to make sure that all the desired controls are pressed, your code needs to work like the following:
This will only evaluate to
TRUE if all the bits set in
secret_style are present in both
held and
change. This method allows additional keys
beyond the ones you are looking for to be pressed and the combo will still be detected. If you want to be even more strict use code like this:
if ((held & change) == secret_style) llOwnerSay("very strict");
This will only evaluate to
TRUE if exactly the specified controls are pressed and no others.
Asking someone to make sure they press 3 keys at the same instant to get them in one control event may be a bit much. An example that will make sure at least one was pressed and the correct 3 are down looks like:
if ((held & change) && (held == secret_style)) llOwnerSay("ouch");
This is saying, "If any key has been pressed and the keys that are down are exactly the right ones, then cause some pain."
Parameter Conversion
Dealing with
held and
change can be hard to keep track of in complex scripts. If you'd rather use the ideas of pressed, down and released you can use code like this to figure out all the logic for you:
control(key id, integer held, integer change) {
integer pressed = held & change;
integer down = held & ~change;
integer released = ~held & change;
integer inactive = ~held & ~change;
if (pressed & CONTROL_LBUTTON) llOwnerSay("click");
}
Keep in mind that
down will not contain keys that have just been pressed even though they are "down". If you don't want that just use
held.
Mouselook Mode vs. Normal Mode
In
mouselook, the default movement keys act a bit different compared to "normal" mode. In ML mode the left mouse button triggers
CONTROL_ML_LBUTTON instead of
CONTROL_LBUTTON. The left/right keys are now used for strafing, so instead of
CONTROL_ROT_LEFT and
CONTROL_ROT_RIGHT (for turning),
CONTROL_LEFT and
CONTROL_RIGHT are triggered.
In "normal" mode
CONTROL_LEFT and
CONTROL_RIGHT can be triggered by holding down
shift and using the left/right keys.
Example
Q: What are the keyboard keys for CONTROL_LEFT and CONTROL_RIGHT? Do they exist?
A: If you hold down the shift key and use left or right when NOT in mouselook, or if you move left or right in mouselook. (Shift-A/D when not in mouselook, A/D in mouselook)
Events |
Agent/Avatar |
Mouselook Jasa SEO Murah Jasa SEO Jasa Google Adwords Jasa Adwords Google Adwords Sepatu Safety Sepatu Futsal Cheapes Hostgator Coupon Link Booking Televisori offerte Notebook Offerte Govr Edo Ziedo Portatile Apple RDAnet Lorks Karikatur Bisnis Modal Kecil Bisnis UKM Berita Terbaru Iklan Baris Jasa SEO Murah SEO Indonesia Konsultan SEO SEO Belajar SEO Penumbuh Rambut Kursus SEO Jam Tangan Casio Grosir Baju Bisnis Online Kerupuk Kulit Social Bookmark Kumpulan Puisi WBC Wonogiri Penumbuh Rambut Jam Tangan Murah Jam Tangan Murah Jam Tangan Casio Penumbuh Rambut Kerupuk Kulit Alat Kantor Laku.com Belanja Online Grosir Eceran Murah dan Aman Jasa SEO Model Jilbab Fine Tableware Permanent Hair Removal island investment development professional makeup artist bali private villa sewa mobil jakarta murah Jual rumah Jakarta Contact Lens Technology