Open pfarnach opened 3 months ago
Thank you for your kind words :)
It seems like Godot is emitting the joy_connection_changed signal after your call into the MultiplayerInput system for some reason.
Do you have a player join/leave system? I'm trying to think through why I don't have this problem in my games and I think it's maybe because I only query for input after the player has already joined, in which case we already know the gamepad is connected. See the the demo player manager's handle_join_input function for what I mean exactly.
If that is not it, here is another thing you could try. It seems like maybe in your case for some reason you need to only get input if the device exists. I can only guess as to why without seeing your code, but perhaps you could try wrapping your input logic inside a check against the is_connected
bool on DeviceInput. For example like this:
var input: DeviceInput
func set_device(device: int):
input = DeviceInput.new(device)
func _process(_delta: float):
if input.is_connected:
pass # your input logic here
Thinking this through more, I think my code example will not work in your case because DeviceInput assumes it's connected when it's created. But in your case this would not be a correct assumption. I realized that I should initialize that variable by checking Input.get_connected_joypads() so I will do that later tonight when I have some time.
Yeah I think the difference is in my case I'm reading Input.get_vector()
from the instant the game starts up (I'm prototyping right now -- in practice this likely won't happen, but it does seem like a valid use case). I'm guessing the joy_connection_changed
signal fires a frame or more after the game starts. Would it be possible to call _create_actions_for_device()
both in _init()
and after the joy_connection_changed
signal fires?
Great idea! I think that idea will work as long as Input.get_connected_joypads returns the connected devices. I will try that tonight too. My concern is that maybe it will return an empty array before the connection changed signals, which would mean I would have no way of knowing which devices to initialize those actions for. I will give it a try.
In the mean time I have added this locally in the reset() function that seems to solve this issue.
# Initialize already connected devices
for id in Input.get_connected_joypads():
_on_joy_connection_changed(id, true)
I have a simple game with two gamepads connected. After following the setup instructions, I was getting an error
Assertion failed: Device 0 has no actions. Maybe the joypad is disconnected.
. After sticking in some print lines, it appears as thoughget_action_name
is getting called before thedevice_actions
dict has a chance to populate in_create_actions_for_device()
. Commenting out theassert(...)
line and adding ahas()
check, likeif device_actions.has(device):
, is a workaround. It looks like there's a bit of a race condition happening.This seems related to https://github.com/matjlars/godot-multiplayer-input/issues/6 except that this happens when the game first starts up and the controllers are already connected.
Love the library, thanks for your work on it!