To change key configuration i need to get the key input but after looking around i havent found any way of doing that using c#.The other way is using the Gd programming language.but i cant do that as my whole script(works) is using c# including the object that has the key detection script so changing the language will couse me a lot of problem:(
-
\$\begingroup\$ I'm not sure if you want to get which key is configured, their state, or how to change them. Si I kind of answered everything, hoping I covered what you want. By the way, I'll also point out that despite the fact that you are using C#, you can still use GDScript in your project (I mean you can use both C# and GDScript in the same project). \$\endgroup\$– TheraotCommented Feb 23 at 21:01
-
\$\begingroup\$ this is useful for my project but i wanted to know how to get a key similiar to using console.readkey \$\endgroup\$– NEWBIECommented Feb 23 at 22:14
-
\$\begingroup\$ As in standard input, like I did for this answwer: What is the correct way to stop a Godot dedicated server (except that is not C#)? \$\endgroup\$– TheraotCommented Feb 23 at 22:17
-
\$\begingroup\$ i made a thread,connected it to my getkey function,called the readstringfromstdn method and got nothing.I think this might be a problem with it not having enough time to get an input but i am not sure as i have never used it before. \$\endgroup\$– NEWBIECommented Feb 24 at 19:03
-
\$\begingroup\$ I think it only works on headless mode. \$\endgroup\$– TheraotCommented Feb 24 at 19:56
2 Answers
Awaiting a key
I believe we can create a custom signal for this:
[Signal]
public delegate void KeyPressedEventHandler();
public override void _Input(InputEvent @event)
{
base._Input(@event);
if (@event is InputEventKey inputKey)
{
EmitSignal(SignalName.KeyPressed);
}
}
And then we should be able to await it:
await ToSignal(this, SignalName.KeyPressed);
General Input
Although I believe you already know how to check if an action is pressed, let us look at it again. You can, for example, do this:
Input.IsActionPressed("Move_Up")
Or this for analog input:
Input.GetActionStrength("Move_Up")
Now that String
must match an action configured in project settings. So we are talking about reading and writing project settings.
However, input is handled a bit different than the rest. There are a couple things to know:
- The
InputMap
gives you access to the input settings. So we will be using that. - What is getting stored in project settings are
InputEvent
s. Yes, the class of objects you get in_Input
. They areResource
s, so they can be saved. And what Godot is doing is matching the input it gets to the stored ones.
Before we go on, I need to point out that manipulating InputMap
on the editor (i.e. tool
scripts) will give you access to the editor settings instead. And yes, you can end up messing them up.
First, to find out if a action is configured we can do this:
if (InputMap.has_action("Action_Name"))
{
GD.Print("The action exists");
}
Second, if you want to find the names of all the actions that are configured do:
foreach (var action_name in InputMap.GetActions())
{
GD.Print(action_name);
}
Third, to get the InputEvent
s associated with an action, you do this:
foreach (var @event in InputMap.ActionGetEvents("My_ActioN"))
{
GD.Print(@event);
}
Fourth, this is what I do to change them:
InputMap.ActionEraseEvents("My_Action");
foreach (var new_event in my_events)
{
InputMap.ActionAddEvent("My_Action", new_event);
}
And I remind you that those events are InputEvent
, so you can get them from _Input
and add them to InputMap
. You probably want to filter them to the device the player is using (e.g. which controller). And remember leaving a way to cancel or restore the original settings.
You, of course, will also want to be able to save these, and for that I remind you that they are Resource
s. So you can use ResourceSaver
and ResourceLoader
.
However, if you rather not...
For keyboard: From
InputEventKey
you can use eitherkeycode
orphysical_keycode
. And you might also want to storealt_pressed
,ctrl_pressed
,shift_pressed
andmeta_pressed
.For mouse:
- From
InputEventMouseButton
you usebutton_index
. - From
InputEventMouseMotion
... I don't have code for this per-se. Instead I have sensitivity and invert axis.
- From
For joystick:
- From
InputEventJoypadButton
you usebutton_index
. - From
InputEventJoypadMotion
you useaxis
andaxis_value
(probably just the sign).
Addendumm: In both cases you identify the device by the
device
property.- From
Note: I'm looking on my GDScript code for the property names. I presume the capitalization is different on C#.
Bonus: if you want to mimic input, there is Input.ActionPress
and Input.ActionRelease
. There is also Input.ParseInputEvent
which requires an InputEvent
. There have been some bugs around these in Godot 4+ (either not doing anything or input getting stuck), so test if ParseInputEvent
works better than ActionPress
and ActionRelease
on your version.
This is the code for getting the key input:
public override void _Input(InputEvent @event)
{
base._Input(@event);
if (@event is InputEventKey inputKey && isRemapping==true)
{
Key c = inputKey.Keycode;
GD.Print(c);
Pressed = inputKey;
GetViewport().SetInputAsHandled();
isRemapping = false;
}
}
-
\$\begingroup\$ Please try what I added to my answer. I can't test C# right now. \$\endgroup\$– TheraotCommented Feb 24 at 21:05