123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- using System;
- using UnityEngine.InputSystem.Composites;
- using UnityEngine.InputSystem.LowLevel;
- namespace UnityEngine.InputSystem.Layouts
- {
- /// <summary>
- /// Mark a field or property as representing/identifying an input control in some form.
- /// </summary>
- /// <remarks>
- /// This attribute is used in different places for different purposes.
- ///
- /// When creating input control layouts (<see cref="InputControlLayout"/>) in C#, applying the
- /// attribute to fields in a state struct (see <see cref="IInputStateTypeInfo"/> or <see cref="GamepadState"/>
- /// for an example) or to properties in an input device (<see cref="InputDevice"/>), will cause an
- /// <see cref="InputControl"/> to be created from the field or property at runtime. The attribute
- /// can be applied multiple times to create multiple input controls (e.g. when having an int field
- /// that represents a bitfield where each bit is a separate button).
- ///
- /// <example>
- /// <code>
- /// public class MyDevice : InputDevice
- /// {
- /// // Adds an InputControl with name=myButton and layout=Button to the device.
- /// [InputControl]
- /// public ButtonControl myButton { get; set; }
- /// }
- /// </code>
- /// </example>
- ///
- /// Another use is for marking <c>string</c> type fields that represent input control paths. Applying
- /// the attribute to them will cause them to automatically use a custom inspector similar to the one
- /// found in the action editor. For this use, only the <see cref="layout"/> property is taken into
- /// account.
- ///
- /// <example>
- /// <code>
- /// public class MyBehavior : MonoBehaviour
- /// {
- /// // In the inspector, shows a control selector that is restricted to
- /// // selecting buttons. As a result, controlPath will be set to path
- /// // representing the control that was picked (e.g. "<Gamepad>/buttonSouth").
- /// [InputControl(layout = "Button")]
- /// public string controlPath;
- ///
- /// protected void OnEnable()
- /// {
- /// // Find controls by path.
- /// var controls = InputSystem.FindControl(controlPath);
- /// //...
- /// }
- /// }
- /// </code>
- /// </example>
- ///
- /// Finally, the attribute is also used in composite bindings (<see cref="InputBindingComposite"/>)
- /// to mark fields that reference parts of the composite. An example for this is <see cref="AxisComposite.negative"/>.
- /// In this use, also only the <see cref="layout"/> property is taken into account while other properties
- /// are ignored.
- ///
- /// <example>
- /// <code>
- /// public class MyComposite : InputBindingComposite<float>
- /// {
- /// // Add a part to the composite called 'firstControl' which expects
- /// // AxisControls.
- /// [InputControl(layout = "Axis")]
- /// public int firstControl;
- ///
- /// // Add a part to the composite called 'secondControl' which expects
- /// // Vector3Controls.
- /// [InputControl(layout = "Vector3")]
- /// public int secondControl;
- ///
- /// //...
- /// }
- /// </code>
- /// </example>
- /// </remarks>
- /// <seealso cref="InputControlLayout"/>
- /// <seealso cref="InputBindingComposite"/>
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]
- public sealed class InputControlAttribute : PropertyAttribute
- {
- /// <summary>
- /// Layout to use for the control.
- /// </summary>
- /// <value>Layout to use for the control.</value>
- /// <remarks>
- /// If this is not set, the system tries to infer the layout type from the value type of
- /// the field or property. If the value type is itself registered as a layout, that layout
- /// will be used (e.g. when you have a property of type <see cref="Controls.ButtonControl"/>, the layout
- /// will be inferred to be "Button"). Otherwise, if a layout with the same name as the type is registered,
- /// that layout will be used (e.g. when you have a field of type <see cref="Vector3"/>, the layout
- /// will be inferred to be "Vector3").
- /// </remarks>
- /// <seealso cref="InputControlLayout"/>
- public string layout { get; set; }
- /// <summary>
- /// Layout variant to use for the control.
- /// </summary>
- /// <value>Layout variant to use for the control.</value>
- public string variants { get; set; }
- /// <summary>
- /// Name to give to the name. If null or empty, the name of the property or
- /// field the attribute is applied to will be used.
- /// </summary>
- /// <value>Name to give to the control.</value>
- /// <seealso cref="InputControl.name"/>
- public string name { get; set; }
- /// <summary>
- /// Storage format to use for the control. If not set, default storage format
- /// for the given <see cref="layout"/> is used.
- /// </summary>
- /// <value>Memory storage format to use for the control.</value>
- /// <seealso cref="InputStateBlock.format"/>
- public string format { get; set; }
- /// <summary>
- /// Usage to apply to the control.
- /// </summary>
- /// <value>Usage for the control.</value>
- /// <remarks>
- /// This property can be used in place of <see cref="usages"/> to set just a single
- /// usage on the control.
- /// </remarks>
- /// <seealso cref="InputControl.usages"/>
- /// <seealso cref="InputControlLayout.ControlItem.usages"/>
- /// <seealso cref="CommonUsages"/>
- public string usage { get; set; }
- /// <summary>
- /// Usages to apply to the control.
- /// </summary>
- /// <value>Usages for the control.</value>
- /// <remarks>
- /// This property should be used instead of <see cref="usage"/> when a control has multiple usages.
- /// </remarks>
- /// <seealso cref="InputControl.usages"/>
- /// <seealso cref="InputControlLayout.ControlItem.usages"/>
- /// <seealso cref="CommonUsages"/>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "According to MSDN, this message can be ignored for attribute parameters, as there are no better alternatives.")]
- public string[] usages { get; set; }
- /// <summary>
- /// Optional list of parameters to apply to the control.
- /// </summary>
- /// <value>Parameters to apply to the control.</value>
- /// <remarks>
- /// An <see cref="InputControl"/> may expose public fields which can be set as
- /// parameters. An example of this is <see cref="Controls.AxisControl.clamp"/>.
- ///
- /// <example>
- /// <code>
- /// public struct MyStateStruct : IInputStateTypeInfo
- /// {
- /// [InputControl(parameters = "clamp,clampMin=-0.5,clampMax=0.5")]
- /// public float axis;
- /// }
- /// </code>
- /// </example>
- /// </remarks>
- /// <seealso cref="InputControlLayout.ControlItem.parameters"/>
- public string parameters { get; set; }
- /// <summary>
- /// Optional list of processors to add to the control.
- /// </summary>
- /// <value>Processors to apply to the control.</value>
- /// <remarks>
- /// Each element in the list is a name of a processor (as registered with
- /// <see cref="InputSystem.RegisterProcessor{T}"/>) followed by an optional
- /// list of parameters.
- ///
- /// For example, <c>"normalize(min=0,max=256)"</c> is one element that puts
- /// a <c>NormalizeProcessor</c> on the control and sets its <c>min</c> field
- /// to 0 and its its <c>max</c> field to 256.
- ///
- /// Multiple processors can be put on a control by separating them with a comma.
- /// For example, <c>"normalize(max=256),scale(factor=2)"</c> puts both a <c>NormalizeProcessor</c>
- /// and a <c>ScaleProcessor</c> on the control. Processors are applied in the
- /// order they are listed.
- /// </remarks>
- /// <seealso cref="InputControlLayout.ControlItem.processors"/>
- /// <seealso cref="InputBinding.processors"/>
- public string processors { get; set; }
- /// <summary>
- /// An alternative name that can be used in place of <see cref="name"/> to find
- /// the control.
- /// </summary>
- /// <value>Alternative name for the control.</value>
- /// <remarks>
- /// This property can be used instead of <see cref="aliases"/> when there is only a
- /// single alias for the control.
- ///
- /// Aliases, like names, are case-insensitive. Any control may have arbitrary many
- /// aliases.
- /// </remarks>
- /// <seealso cref="InputControl.aliases"/>
- /// <seealso cref="InputControlLayout.ControlItem.aliases"/>
- public string alias { get; set; }
- /// <summary>
- /// A list of alternative names that can be used in place of <see cref="name"/> to
- /// find the control.
- /// </summary>
- /// <value>Alternative names for the control.</value>
- /// <remarks>
- /// This property should be used instead of <see cref="alias"/> when a control has
- /// multiple aliases.
- ///
- /// Aliases, like names, are case-insensitive. Any control may have arbitrary many
- /// aliases.
- /// </remarks>
- /// <seealso cref="InputControl.aliases"/>
- /// <seealso cref="InputControlLayout.ControlItem.aliases"/>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "According to MSDN, this message can be ignored for attribute parameters, as there are no better alternatives.")]
- public string[] aliases { get; set; }
- public string useStateFrom { get; set; }
- public uint bit { get; set; } = InputStateBlock.InvalidOffset;
- /// <summary>
- /// Offset in bytes to where the memory of the control starts. Relative to
- /// the offset of the parent control (which may be the device itself).
- /// </summary>
- /// <value>Byte offset of the control.</value>
- /// <remarks>
- /// If the attribute is applied to fields in an <see cref="InputControlLayout"/> and
- /// this property is not set, the offset of the field is used instead.
- ///
- /// <example>
- /// <code>
- /// public struct MyStateStruct : IInputStateTypeInfo
- /// {
- /// public int buttons;
- ///
- /// [InputControl] // Automatically uses the offset of 'axis'.
- /// public float axis;
- /// }
- ///
- /// [InputControlLayout(stateType = typeof(MyStateStruct))]
- /// public class MyDevice : InputDevice
- /// {
- /// }
- /// </code>
- /// </example>
- /// </remarks>
- /// <seealso cref="InputControlLayout.ControlItem.offset"/>
- public uint offset { get; set; } = InputStateBlock.InvalidOffset;
- /// <summary>
- /// Size of the memory storage for the control in bits.
- /// </summary>
- /// <value>Size of the control in bits.</value>
- /// <remarks>
- /// If the attribute is applied to fields in an <see cref="InputControlLayout"/> and
- /// this property is not set, the size is taken from the field.
- ///
- /// <example>
- /// <code>
- /// public struct MyStateStruct : IInputStateTypeInfo
- /// {
- /// public int buttons;
- ///
- /// [InputControl] // Automatically uses sizeof(float).
- /// public float axis;
- /// }
- ///
- /// [InputControlLayout(stateType = typeof(MyStateStruct))]
- /// public class MyDevice : InputDevice
- /// {
- /// }
- /// </code>
- /// </example>
- /// </remarks>
- /// <seealso cref="InputControlLayout.ControlItem.sizeInBits"/>
- /// <seealso cref="InputStateBlock.sizeInBits"/>
- public uint sizeInBits { get; set; }
- public int arraySize { get; set; }
- /// <summary>
- /// Display name to assign to the control.
- /// </summary>
- /// <value>Display name for the control.</value>
- /// <seealso cref="InputControl.displayName"/>
- /// <seealso cref="InputControlLayout.ControlItem.displayName"/>
- public string displayName { get; set; }
- /// <summary>
- /// Short display name to assign to the control.
- /// </summary>
- /// <value>Short display name for the control.</value>
- /// <seealso cref="InputControl.shortDisplayName"/>
- /// <seealso cref="InputControlLayout.ControlItem.shortDisplayName"/>
- public string shortDisplayName { get; set; }
- /// <summary>
- /// Whether the control is noisy. Off by default.
- /// </summary>
- /// <value>Whether control is noisy.</value>
- /// <seealso cref="InputControl.noisy"/>
- /// <seealso cref="InputControlLayout.ControlItem.isNoisy"/>
- public bool noisy { get; set; }
- /// <summary>
- /// Whether the control is synthetic. Off by default.
- /// </summary>
- /// <value>Whether control is synthetic.</value>
- /// <seealso cref="InputControl.synthetic"/>
- /// <seealso cref="InputControlLayout.ControlItem.isSynthetic"/>
- public bool synthetic { get; set; }
- /// <summary>
- /// Default state to write into the control's memory.
- /// </summary>
- /// <value>Default memory state for the control.</value>
- /// <remarks>
- /// This is not the default <em>value</em> but rather the default memory state, i.e.
- /// the raw memory value read and the processed and returned as a value. By default
- /// this is <c>null</c> and result in a control's memory to be initialized with all
- /// zeroes.
- /// </remarks>
- /// <seealso cref="InputControlLayout.ControlItem.defaultState"/>
- public object defaultState { get; set; }
- /// <summary>
- /// Lower limit for values of the control.
- /// </summary>
- /// <value>Lower limit for values of the control.</value>
- /// <remarks>
- /// This is null by default in which case no lower bound is applied to the TODO
- /// </remarks>
- public object minValue { get; set; }
- public object maxValue { get; set; }
- }
- }
|