Step 1 The state struct
The first step is to create a C# struct that represents the form in which the system receives and stores input, and also describes the InputControl instances that the Input System must create for the Device in order to retrieve its state.
// A "state struct" describes the memory format that a Device uses. Each Device can
// receive and store memory in its custom format. InputControls then connect to
// the individual pieces of memory and read out values from them.
//
// If it's important for the memory format to match 1:1 at the binary level
// to an external representation, it's generally advisable to use
// LayoutLind.Explicit.
[StructLayout(LayoutKind.Explicit, Size = 32)]
public struct MyDeviceState : IInputStateTypeInfo
{
// You must tag every state with a FourCC code for type
// checking. The characters can be anything. Choose something that allows
// you to easily recognize memory that belongs to your own Device.
public FourCC format => new FourCC('M', 'Y', 'D', 'V');
// InputControlAttributes on fields tell the Input System to create Controls
// for the public fields found in the struct.
// Assume a 16bit field of buttons. Create one button that is tied to
// bit #3 (zero-based). Note that buttons don't need to be stored as bits.
// They can also be stored as floats or shorts, for example. The
// InputControlAttribute.format property determines which format the
// data is stored in. If omitted, the system generally infers it from the value
// type of the field.
[InputControl(name = "button", layout = "Button", bit = 3)]
public ushort buttons;
// Create a floating-point axis. If a name is not supplied, it is taken
// from the field.
[InputControl(layout = "Axis")]
public short axis;
}
The Input System's layout mechanism uses InputControlAttribute annotations to add Controls to the layout of your Device. For details, see the layout system documentation.
With the state struct in place, you now have a way to send input data to the Input System and store it there. The next thing you need is an InputDevice that uses your custom state struct and represents your custom Device.