How to get C# compiler to stop complaining about this variable's type

Godot Version

v4.4

Question

Starting to learn C#, ran into a problem with the compiler. In gdscript this works because there’s no possibility that it’ll try to read a non-InputEventKey InputEvent as an InputEventKey

func remove_inputeventkey(action:String,keycode)->void:
	for event in InputMap.action_get_events(action):# same as `for event in range(InputMap.action_get_events(action))`
		if event is InputEventKey and event.get_physical_keycode_with_modifiers() == keycode:
			InputMap.action_erase_event(action,event)
			break

Whereas in C# the compiler sees the same thing and goes YOU SILLY GOOSE

public void remove_inputeventkey(string action,int keycode){
	var actioninputs = InputMap.ActionGetEvents(action);
	var input = actioninputs[0];
	for (int i = 0; i < actioninputs.Count; i++){
		input = actioninputs[i];
		if (input is InputEventKey){
			if (input.GetPhysicalKeycode() == keycode){
				InputMap.ActionEraseEvent(action,input);
				break;
}}}}

so uh yeah I know what the problem is but… what do

This is because input (which in this case is an InputEvent) does not contain a definition for GetPhysicalKeycode.

I modifed your code for better readability AND to follow best naming practices for C#, and also fixed the issue for you:

public void RemoveInputEventKey(string action, int keycode)
{
    Array<InputEvent> actioninputs = InputMap.ActionGetEvents(action);
    InputEvent input;
    foreach (InputEvent inputEvent in actioninputs)
    {
        if (inputEvent is not InputEventKey inputKey)
        {
            continue;
        }

        if (inputKey.GetPhysicalKeycode() != (Key)keycode)
        {
            continue;
        }
        
        InputMap.ActionEraseEvent(action, inputKey);
        break;
    }
}
1 Like

oh much thanks
the reason I left the name in snakecase was because I’m trying to make the autoload script it’s a part of interchangeable with one in gdscript, just add a number and boom csharp

ok yeah so uh actually it didn’t work, got some tasty errors
The non-generic type 'Array' cannot be used with type arguments
and
The variable 'input' is declared but never used

This works

public void RemoveInputEventKey(string action, int keycode)
{
	Godot.Collections.Array<InputEvent> actioninputs = InputMap.ActionGetEvents(action);
	foreach (InputEvent inputEvent in actioninputs)
	{
		if (inputEvent is not InputEventKey inputKey)
		{
			continue;
		}
		if (inputKey.GetPhysicalKeycode() != (Key)keycode)
		{
			continue;
		}
		InputMap.ActionEraseEvent(action, inputKey);
		break;
	}
}

but what is inputKey? Why does that work, it looks like it was declared in an if

This is called Pattern Matching.

One of those wasn’t an error but a warning which can be ignored, and the first one wasn’t a problem with my code, but the fact that you were using the incorrect Array type. You need to pay attention because both C# and Godot has their own collections.

1 Like