How do I create a blank InputEvent in C# and then assign a value to it

Godot Version

v4.4

Question

I’m trying to port my code that adds a new InputEventKey to a specified InputAction to C#

func add_inputeventkey(action:String, keycode:int)->void:
	for event in InputMap.action_get_events(action):
		if event is InputEventKey and event.get_physical_keycode_with_modifiers() == keycode:
			print("Key assignment redundancy: tried to attach physical keycode "+str(keycode)+" to "+action+", to which it was already assigned")
			return
	var newinput = InputEventKey.new()
	InputMap.action_add_event(action,newinput)
	newinput.set_physical_keycode(keycode)
public static void add_inputeventkey(string action, int keycode)
{
	Godot.Collections.Array<InputEvent> actioninputs = InputMap.ActionGetEvents(action);
	foreach (InputEvent input in actioninputs)
	{
		if (input is InputEventKey inputKey){if (inputKey.GetPhysicalKeycodeWithModifiers() == (Key)keycode)
		{
			GD.Print("Key assignment redundancy: tried to attach physical keycode "+GD.VarToStr(keycode)+" to "+GD.VarToStr(action)+", to which it was already assigned");
			return;
		}}
	}
	InputEventKey newinput;
	InputMap.ActionAddEvent(action, newinput);
	newinput.SetPhysicalKeycode((Key)keycode);
	return;
	}
}

the broken part being

InputEventKey newinput;
InputMap.ActionAddEvent(action, newinput);
newinput.SetPhysicalKeycode((Key)keycode);

Use of unassigned local variable 'newinput' I mean yeah what do you want

Your line InputEventKey newinput; would be InputEventKey newinput = new InputEventKey() in order to match the GDScript code.

In C# you still need to explicitly construct the object with new. Declaring a variable of that type isn’t enough on its own.

1 Like

Thanks but uh now I have a new problem?? The function only runs the first time it’s called, what’s up with that
(for context it’s part of an autoload that gets called a lot)

You are probably only ever calling it once. There’s nothing about the function itself that you shared that should make it behave differently on subsequent calls.

One of the nice things about C# is the really good debugging. I like to use Jetbrains Rider for this personally, but Visual Studio Code is also a popular option.

If you…

  1. Set up your IDE like Rider or VS Code for your Godot project
  2. Place a breakpoint at place(s) before the function gets called (In Rider you can do this by clicking on the line number, in VSC probably the same though I haven’t used it to be sure)
  3. Run the program in debug mode through your IDE

…Then the program will pause there at any breakpoint that you set. It will let you inspect the current state of variables and all to see what there isn’t as you expect, and let you step through things one line at a time to find where things go wrong. (Or, if it doesn’t pause there, then this tells you that the code is never run at all, and your problem is in whatever other code you thought was going to make that code run in the first place.)

Here’s a related tutorial for VS Code: C# Development with Godot and Visual Studio Code Tutorial

But you shouldn’t need a Godot specific tutorial - any help online about opening your C# project and using the debugger in whichever IDE you choose should be applicable.

euhhhhhhhhhh fine I’ll get an IDE, is neovim fine (I like suffering)
but also (string action, int keycode)? The blocks calling it are

func setmotion_wasd()->void:
	utils2.add_inputeventkey("playr1_jump",KEY_W);utils2.remove_inputeventkey("playr1_jump",KEY_UP);utils2.add_inputeventkey("camrot_up",KEY_UP)
	utils2.add_inputeventkey("playr1_left",KEY_A);utils2.remove_inputeventkey("playr1_left",KEY_LEFT);utils2.add_inputeventkey("camrot_left",KEY_LEFT)
	utils2.add_inputeventkey("playr1_sqat",KEY_S);utils2.remove_inputeventkey("playr1_sqat",KEY_DOWN);utils2.add_inputeventkey("camrot_down",KEY_DOWN)
	utils2.add_inputeventkey("playr1_righ",KEY_D);utils2.remove_inputeventkey("playr1_righ",KEY_RIGHT);utils2.add_inputeventkey("camrot_righ",KEY_RIGHT)
	#print("motion controls set to wasd")
func setmotion_arrows()->void:
	utils2.add_inputeventkey("playr1_jump",KEY_UP);utils2.remove_inputeventkey("playr1_jump",KEY_W);utils2.add_inputeventkey("camrot_up",KEY_W)
	utils2.add_inputeventkey("playr1_left",KEY_LEFT);utils2.remove_inputeventkey("playr1_left",KEY_A);utils2.add_inputeventkey("camrot_left",KEY_A)
	utils2.add_inputeventkey("playr1_sqat",KEY_DOWN);utils2.remove_inputeventkey("playr1_sqat",KEY_S);utils2.add_inputeventkey("camrot_down",KEY_S)
	utils2.add_inputeventkey("playr1_righ",KEY_RIGHT);utils2.remove_inputeventkey("playr1_righ",KEY_D);utils2.add_inputeventkey("camrot_righ",KEY_D)
	#print("motion controls set to arrows")

and the gdscript version can go again just fine

bracket mismanagement :woman_facepalming:

public static void add_inputeventkey(string action, int keycode)
{
	Godot.Collections.Array<InputEvent> actioninputs = InputMap.ActionGetEvents(action);
	foreach (InputEvent input in actioninputs)
	{
		if (input is InputEventKey inputKey 
&& inputKey.GetPhysicalKeycodeWithModifiers() == (Key)keycode)
		{
			GD.Print("Key assignment redundancy: tried to attach physical keycode "+GD.VarToStr(keycode)+" to "+GD.VarToStr(action)+", to which it was already assigned");
			return;
		}
	}
	InputEventKey newinput = new InputEventKey();
	InputMap.ActionAddEvent(action, newinput);
	newinput.SetPhysicalKeycode((Key)keycode);
}

(no the broken version isn’t here, even my original example got the {}s right)