Hello, I’m writing an custom InputDevice for a CAN bus device. In case you don’t know (I didn’t) CAN stands for controller area network and is used extensively in automotive applications. I’m using drivers, plugins, and the CANlib SDK by Kvaser to read the messages from this device into Unity. No problem there, getting messages streaming into InputSystem and even updating one StickControl of my custom InputDevice correctly.
But this CAN device does not have just one joystick. It has 5. And ~20 buttons. Therefore, it does not report its state all in one CAN message, but in about 4. So that’s where my issue arises. I get 4 messages which I filter by its messageID. Here’s an example of the two main ones:
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
So in my code, I filter each message.
-
Message 1
-
bytes 0 and 1 go to a VC2B stick control.
-
bytes 2 and 3 go to a VC2B stick control.
-
byte 4 goes to a bunch of BIT aligned button controls
-
etc
-
Message 2
-
bytes 0 and 1 go to a VC2B stick control.
-
bytes 2 and 3 go to a VC2B stick control.
-
byte 4 goes to a bunch of BIT aligned button controls
-
etc
-
etc
Initially, I was using InputSystem.QueueStateEvent(myDevice,new MyDeviceState(){...});
, just setting the fields I could at the time with the message I received. Of course, I realized that the other fields were getting set to their defaults and this was no good. So most recently, I’ve been trying to use InputSystem.QueueDeltaStateEvent(myDevice.Joystick,Vector2.zero);
, but when I do that my device gets removed. Is this a bug? Am I doing it wrong?
I haven’t found many examples of using QueueDeltaStateEvent, except in this script on GitHub and this guide and I thought I did it the same way. One thing - I’m using async while loops to read messages coming in, so QueueDeltaStateEvent might be getting called on a different thread, but my understanding was that these methods were thread safe, so I don’t know. Any guidance on how I’m supposed to use this or if there is a better way to do partial state updates would be very appreciated.
Bonus Question: I can also send commands to the device to turn on/off LEDs and make beeps, etc. How do I correctly override ExecuteCommand to send these commands via my Canlib library? So far, I’ve just worked around this method by calling my library methods directly, but it would be nice to know if there was an “InputSystem way” I could hook that up.