如何在 Unity 输入系统中向 HID 设备发送数据

How to send data to HID device in Unity Input System

我设法在 Unity 输入系统中实现了 HID 设备,我可以轻松地从中读取。 但是如何将数据发送回HID设备呢?

这是我的 IInputDeviceCommandInfo 实现:

    [StructLayout(LayoutKind.Explicit)]
    internal struct MyControlCommand : IInputDeviceCommandInfo
    {
        public static FourCC Type { get { return new FourCC("HIDO"); } }
  
        [FieldOffset(0)]
        public byte res;

        [FieldOffset(1)]
        public byte magic; 

        [FieldOffset(2)]
        public byte DataType;

        [FieldOffset(3)]
        public short Data;
 
        public FourCC typeStatic
        {
            get { return Type; }
        }

        public static MyControlCommand Create(byte dataType, short data)
        {
            return new MyControlCommand
            { 
                magic = 0x7e,
                DataType = dataType,
                Data = data
            };
        }
    }

我想发送这些字节:

0
0x7e
0x04
0xfff

所以我用了:

var c = MyControlCommand.Create(0x04, 0xfff);
var res = current.ExecuteCommand(ref c);

res变量得到-1,所以不成功

我设法使用 HidSharp 库和我自己的 HID 实现与设备通信(以上字节工作正常),但 Unity 很顽固...

感谢帮助!

好的,这不是一个容易解决的问题:

问题是 IInputDeviceCommandInfo 不会强制用户将 Field(0) 实现为 InputDeviceCommandInputDeviceCommand 必须在Field(0)处添加偏移量,其他字段必须分别移位

第二个问题是我的设备需要不同大小的输出数据。可能 OS 检查大小是否匹配(capabilities.outputReportSize 中描述符报告的大小和实际要发送的大小)。

所以我在结构中添加了缺失的字段并且它起作用了:

[StructLayout(LayoutKind.Explicit, Size = kSize)]
    internal struct Command2 : IInputDeviceCommandInfo
    {
        public static FourCC Type => new FourCC('H', 'I', 'D', 'O');
        public FourCC typeStatic => Type;

        internal const int kSize = InputDeviceCommand.BaseCommandSize + 31; //<---- calculate manually
          
        [FieldOffset(0)] public InputDeviceCommand baseCommand; // <--- required, overlaps the rest, that's the trick to avoid Marshalling struct to byte array, that I use 
        [FieldOffset(InputDeviceCommand.BaseCommandSize + 0)] public byte zero; // <--- don't know why
        [FieldOffset(InputDeviceCommand.BaseCommandSize + 1)] public byte magic;
        [FieldOffset(InputDeviceCommand.BaseCommandSize + 2)] public byte reportId;
        [FieldOffset(InputDeviceCommand.BaseCommandSize + 3)] public short payload;
      
         
        public static Command2 Create(byte id, short payload)
        {
            return new Command2
            {
                baseCommand = new InputDeviceCommand(Type, kSize),
                magic = 0x7e,
                reportId = id,
                payload = payload
            };
        }
    }

希望有人能从中受益。