1
\$\begingroup\$

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:(

\$\endgroup\$
6
  • \$\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\$
    – Theraot
    Commented 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\$
    – NEWBIE
    Commented 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\$
    – Theraot
    Commented 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\$
    – NEWBIE
    Commented Feb 24 at 19:03
  • \$\begingroup\$ I think it only works on headless mode. \$\endgroup\$
    – Theraot
    Commented Feb 24 at 19:56

2 Answers 2

0
\$\begingroup\$

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 InputEvents. Yes, the class of objects you get in _Input. They are Resources, 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 InputEvents 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 Resources. So you can use ResourceSaver and ResourceLoader.

However, if you rather not...

  • For keyboard: From InputEventKey you can use either keycode or physical_keycode. And you might also want to store alt_pressed, ctrl_pressed, shift_pressed and meta_pressed.

  • For mouse:

    • From InputEventMouseButton you use button_index.
    • From InputEventMouseMotion... I don't have code for this per-se. Instead I have sensitivity and invert axis.
  • For joystick:

    • From InputEventJoypadButton you use button_index.
    • From InputEventJoypadMotion you use axis and axis_value (probably just the sign).

    Addendumm: In both cases you identify the device by the device property.

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.

\$\endgroup\$
0
\$\begingroup\$

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;
      }
  }
\$\endgroup\$
1
  • \$\begingroup\$ Please try what I added to my answer. I can't test C# right now. \$\endgroup\$
    – Theraot
    Commented Feb 24 at 21:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .