Hello
I have seen that in the forum there are a lot of questions about RegisterKeyMapping
, and the guide only mentions it in passing.
And personally you should let a user edit the keys he is continuously using.
That it would be nice if FiveM would allow multiple categories in the future to be able to configure it correctly and always have a prefix of “Fivem -”.
Misuse of IsControlPressed
There are many resources that use something similar to this:
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
if IsControlPressed(1, 75) then
-- Code
end
end
end)
It is true that sometimes it is necessary, for example for the interact key, but not for adding new functionalities, Such as opening your custom nui or the menu you want.
I want to make this clear
This also causes your resource to always be consuming 0.2ms and in many cases unnecessarily adding a RegisterKeyMapping.
Use of RegisterKeyMapping
Some of you may already know the use of RegisterKeyMapping, ut I haven’t seen much in depth information or questions except RegisterKeyMapping - Get the right hash to read the current binding or Get_key_mapping or Create GET_KEY_MAPPING.
The truth is that it is a pity that it is not used so much, since in the RP servers you generally cannot modify the keys.
And if you don’t like where is the key to talk on the radio?
Or do you prefer to have an interaction menu on a key “away” from the “common keys” because you don’t use it?
This in most servers does not allow you to configure almost nothing, and I say almost nothing, because the resource programmers are gradually modifying their resources.
(I speak always from my experience with RP servers).
I will put the typical ways of how to do a RegisterKeyMapping, although this is not a mystery and there are other tutorials that cover it. Example: Using the new console key bindings – FiveM Cookbook
Typical ways of how to do a RegisterKeyMapping
Normal use of RegisterKeyMapping
RegisterKeyMapping("handsup", "Hands Up", "keyboard", "i")
RegisterCommand("handsup",function(source)
-- Code
end)
“Toggle” use
+
Command → When key down
-
Command → When key up
RegisterCommand('+handsup', function()
-- Code
end, false)
RegisterCommand('-handsup', function()
-- Code
end, false)
RegisterKeyMapping('+handsup', 'Hands Up', 'keyboard', 'i')
But this does not resolve several issues.
- How to obtain the actual key mapping configuration
- How we manage it with a NUI with
SetNuiFocus(true, true)
Obtain actual key mapping
This is mainly taken from: RegisterKeyMapping - Get the right hash to read the current binding
Although it really doesn’t make it very clear what it does and can be confusing.
I would also like to thank the creator of the post, since he has solved my doubts. @Markus1812
- Get name command and put in FiveM Hash Generator
This is for get hash key. - Use
GetControlInstructionalButton
to return input
RegisterKeyMapping("handsup", "Hands Up", "keyboard", "i")
RegisterCommand("handsup",function(source)
-- If you like use string can use: ~INPUT_7066E9F8~
-- Remove INPUT_ and get 7066E9F8. This is in hex, and if you put 0x the code treats it as hexadecimal
local button = GetControlInstructionalButton(2, 0x7066E9F8 , 1)
end)
If you like use in AddTextComponentString
you can use INPUT_7066E9F8
. See RegisterKeyMapping - Get the right hash to read the current binding for a more detailed example
If page down this is script to get hash, if you like made in lua or c#, enjoy
Javascript function to get hash
function HashString(command) {
let hash = 0;
let string = command.toLowerCase();
for(i=0; i < string.length; i++) {
let letter = string[i].charCodeAt();
hash = hash + letter;
hash += (hash << 10 >>> 0);
hash ^= (hash >>> 6);
hash = hash >>> 0
}
hash += (hash << 3);
if (hash < 0) {
hash = hash >>> 0
}
hash ^= (hash >>> 11);
hash += (hash << 15);
if (hash < 0) {
hash = hash >>> 0
}
return hash.toString(16).toUpperCase();
}
GetControlInstructionalButton
get for example b_1015
or t_V
.
- ‘
t_...
’ is character - ‘
b_...
’ is special character
The problem of special character: on different keyboards, have different numbers
I use one diccionary strings to convert special characters in javascript key code i use: https://keycode.info/ for getter key codes.
Why use javascript names key? Because if you like send to nui interface, but we will see that in the next point
I leave my list, but some people may need to add their own or change them.
Special key codes
WheelMouseMove and MouseClick is to differentiate events in NUI
SpecialkeyCodes={
['b_116']='WheelMouseMove.Up',
['b_115']='WheelMouseMove.Up',
['b_100']='MouseClick.LeftClick',
['b_101']='MouseClick.RightClick',
['b_102']='MouseClick.MiddleClick',
['b_103']='MouseClick.ExtraBtn1',
['b_104']='MouseClick.ExtraBtn2',
['b_105']='MouseClick.ExtraBtn3',
['b_106']='MouseClick.ExtraBtn4',
['b_107']='MouseClick.ExtraBtn5',
['b_108']='MouseClick.ExtraBtn6',
['b_109']='MouseClick.ExtraBtn7',
['b_110']='MouseClick.ExtraBtn8',
['b_1015']='AltLeft',
['b_1000']='ShiftLeft',
['b_2000']='Space',
['b_1013']='ControlLeft',
['b_1002']='Tab',
['b_1014']='ControlRight',
['b_140']='Numpad4',
['b_142']='Numpad6',
['b_144']='Numpad8',
['b_141']='Numpad5',
['b_143']='Numpad7',
['b_145']='Numpad9',
['b_200']='Insert',
['b_1012']='CapsLock',
['b_170']='F1',
['b_171']='F2',
['b_172']='F3',
['b_173']='F4',
['b_174']='F5',
['b_175']='F6',
['b_176']='F7',
['b_177']='F8',
['b_178']='F9',
['b_179']='F10',
['b_180']='F11',
['b_181']='F12',
['b_194']='ArrowUp',
['b_195']='ArrowDown',
['b_196']='ArrowLeft',
['b_197']='ArrowRight',
['b_1003']='Enter',
['b_1004']='Backspace',
['b_198']='Delete',
['b_199']='Escape',
['b_1009']='PageUp',
['b_1010']='PageDown',
['b_1008']='Home',
['b_131']='NumpadAdd',
['b_130']='NumpadSubstract',
['b_1002']='CapsLock',
['b_211']='Insert',
['b_210']='Delete',
['b_212']='End',
['b_1055']='Home',
['b_1056']='PageUp',
}
Okay, this is very good. But how do I connect it to my nui interface?
With this information, let’s get down to work. I made one function for “translate” keys into something readable for javascript
function translateKey(key)
if (string.find(key, "t_")) then
return string.gsub(key, "t_", "")
else
-- My global variable of special characters call SpecialkeyCodes
return "SpecialCharacter."..SpecialkeyCodes[key]
end
end
Modify RegisterKeyMapping for “toggle” system.
Why? when you use setNuiFocus, the keyup event in javascript is fired as well. this event is the one we are going to use to close the NUI, what we want is to keep it until we press again.
For this reason we have to control when we stop pressing to start listening to the keyUp event.
RegisterCommand('+handsup', function()
local key = GetControlInstructionalButton(2, 0xF53DC64D, true)
local keyName = translateKey(key)
SetNuiFocus(true, true)
SendNUIMessage({
type="open",
closeCharacterName=keyName
})
end, false)
RegisterCommand('-handsup', function()
SendNUIMessage({
type="keyupFinish"
})
end, false)
RegisterKeyMapping('+handsup', 'Hands Up', 'keyboard', 'i')
In javascript listen
disableCheckKey=true;
window.addEventListener("message",(ev)=>{
if(event.type=="open"){
this.disableCheckKey=true;
/*Your code for show UI*/
}
if(event.type=="keyupFinish"){
/*
setTimeout? Why? -> The event is triggered too quickly, so it is a limitation to avoid failures
*/
setTimeout(() => {
this.disableCheckKey=false;
}, 500);
}
})
window.addEventListener("keyup",(ev)=>{
if(this.disableCheckKey){return;}
if(this.keyString.includes("SpecialCharacter")){
/* This need control with:
- MouseClick -> mouse up event
- WheelMouseMove -> wheel event
To avoid repeating code, I am not going to put it
*/
if(this.keyString.includes("WheelMouseMove")||this.keyString.includes("MouseClick")){
return;
}
if(ev.code==this.keyString.replace("SpecialCharacter.","")){
/* Your code to close ui */
}
}else{
if(ev.key.toLocaleLowerCase()==this.keyString.toLocaleLowerCase()){
/* Your code to close ui */
}
}
})
Goodbye and thx for reading to end