diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/InputControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/InputControl.cs
index 5cfa3b49b8..4634d67af7 100644
--- a/Packages/com.unity.inputsystem/InputSystem/Controls/InputControl.cs
+++ b/Packages/com.unity.inputsystem/InputSystem/Controls/InputControl.cs
@@ -119,11 +119,8 @@ public abstract class InputControl
/// Lookup of names is case-insensitive.
///
/// This is set from the name of the control in the layout.
+ /// See , , and .
///
- ///
- ///
- ///
- ///
public string name => m_Name;
////TODO: protect against empty strings
@@ -143,8 +140,9 @@ public abstract class InputControl
/// For nested controls, the display name will include the display names of all parent controls,
/// i.e. the display name will fully identify the control on the device. For example, the display
/// name for the left D-Pad button on a gamepad is "D-Pad Left" and not just "Left".
+ ///
+ /// There is a short name version, see .
///
- ///
public string displayName
{
get
@@ -173,9 +171,8 @@ public string displayName
/// For nested controls, the short display name will include the short display names of all parent controls,
/// that is, the display name will fully identify the control on the device. For example, the display
/// name for the left D-Pad button on a gamepad is "D-Pad \u2190" and not just "\u2190". Note that if a parent
- /// control has no short name, its long name will be used instead.
+ /// control has no short name, its long name will be used instead. See .
///
- ///
public string shortDisplayName
{
get
@@ -202,11 +199,11 @@ public string shortDisplayName
///
/// Allocates on first hit. Paths are not created until someone asks for them.
///
+ /// For more details on the path see .
+ ///
///
/// Example: "/gamepad/leftStick/x"
///
- ///
- ///
public string path
{
get
@@ -218,7 +215,7 @@ public string path
}
///
- /// Layout the control is based on.
+ /// Layout name for the control it is based on.
///
///
/// This is the layout name rather than a reference to an as
@@ -240,25 +237,27 @@ public string path
///
///
/// This is the root of the control hierarchy. For the device at the root, this
- /// will point to itself.
+ /// will point to itself (See ).
///
- ///
public InputDevice device => m_Device;
///
- /// The immediate parent of the control or null if the control has no parent
- /// (which, once fully constructed) will only be the case for InputDevices).
+ /// The immediate parent of the control.
///
- ///
+ ///
+ /// The immediate parent of the control or null if the control has no parent
+ /// (which, once fully constructed, will only be the case for InputDevices).
+ /// See the related field.
+ ///
public InputControl parent => m_Parent;
///
- /// List of immediate children.
+ /// List of immediate child controls below this.
///
///
/// Does not allocate.
+ /// See the related field.
///
- ///
public ReadOnlyArray children =>
new ReadOnlyArray(m_Device.m_ChildrenForEachControl, m_ChildStartIndex, m_ChildCount);
@@ -278,34 +277,38 @@ public string path
/// control to use for certain standardized situation without having to know the particulars of
/// the device or platform.
///
- ///
- ///
- /// // Bind to any control which is tagged with the "Back" usage on any device.
- /// var backAction = new InputAction(binding: "*/{Back}");
- ///
- ///
- ///
/// Note that usages on devices work slightly differently than usages of controls on devices.
/// They are also queried through this property but unlike the usages of controls, the set of
/// usages of a device can be changed dynamically as the role of the device changes. For details,
/// see . Controls, on the other hand,
/// can currently only be assigned usages through layouts (
/// or ).
+ ///
+ /// can be used to add a device.
+ /// can be used to remove a device.
///
- ///
- ///
- ///
- ///
- ///
- ///
+ ///
+ ///
+ /// // Bind to any control which is tagged with the "Back" usage on any device.
+ /// var backAction = new InputAction(binding: "*/{Back}");
+ ///
+ ///
public ReadOnlyArray usages =>
new ReadOnlyArray(m_Device.m_UsagesForEachControl, m_UsageStartIndex, m_UsageCount);
- // List of alternate names for the control.
+ ///
+ /// List of alternate names for the control.
+ ///
+ ///
+ /// List of aliased alternate names for the control.
+ /// An example of an alias would be 'North' for the 'Triangle' button on a Playstation pad (or 'Y' button on Xbox pad).
+ ///
public ReadOnlyArray aliases =>
new ReadOnlyArray(m_Device.m_AliasesForEachControl, m_AliasStartIndex, m_AliasCount);
- // Information about where the control stores its state.
+ ///
+ /// Information about where the control stores its state, such as format, offset and size.
+ ///
public InputStateBlock stateBlock => m_StateBlock;
///
@@ -377,9 +380,10 @@ internal set
/// input from an actual physical control whereas "<Gamepad>/leftStick/left"
/// represents input from a made-up control. If, however, the "left" button is the only
/// viable pick, it will be accepted.
+ ///
+ /// A control layout will specify if it is synthetic using .
+ /// See .
///
- ///
- ///
public bool synthetic
{
get => (m_ControlFlags & ControlFlags.IsSynthetic) != 0;
@@ -395,8 +399,11 @@ internal set
///
/// Fetch a control from the control's hierarchy by name.
///
+ /// A control path. See .
///
- /// Note that path matching is case-insensitive.
+ /// Note that matching is case-insensitive.
+ /// (see ).
+ /// An alternative method is .
///
///
///
@@ -406,9 +413,6 @@ internal set
///
///
/// cannot be found.
- ///
- ///
- ///
public InputControl this[string path]
{
get
@@ -427,30 +431,34 @@ public InputControl this[string path]
/// Type of values produced by the control.
///
/// This is the type of values that are returned when reading the current value of a control
- /// or when reading a value of a control from an event.
+ /// or when reading a value of a control from an event with .
+ /// The size can be determined with .
///
- ///
- ///
public abstract Type valueType { get; }
///
/// Size in bytes of values that the control returns.
///
- ///
+ ///
+ /// The type can be determined with .
+ ///
public abstract int valueSizeInBytes { get; }
///
/// Compute an absolute, normalized magnitude value that indicates the extent to which the control
/// is actuated. Shortcut for .
///
- /// Amount of actuation of the control or -1 if it cannot be determined.
- ///
- ///
+ ///
+ /// Amount of actuation of the control or -1 if it cannot be determined.
+ ///
public float magnitude => EvaluateMagnitude();
///
- /// Return a string representation of the control useful for debugging.
+ /// Return a string representation of the control.
///
+ ///
+ /// Return a string representation of the control. Useful for debugging.
+ ///
/// A string representation of the control.
public override string ToString()
{
@@ -500,23 +508,48 @@ public unsafe float EvaluateMagnitude()
/// Compute an absolute, normalized magnitude value that indicates the extent to which the control
/// is actuated in the given state.
///
+ ///
+ /// Magnitudes do not make sense for all types of controls. For example, for a control that represents
+ /// an enumeration of values (such as ), there is no meaningful
+ /// linear ordering of values (one could derive a linear ordering through the actual enum values but
+ /// their assignment may be entirely arbitrary; it is unclear whether a state of
+ /// has a higher or lower "magnitude" as a state of ).
+ ///
+ /// Controls that have no meaningful magnitude will return -1 when calling this method. Any negative
+ /// return value should be considered an invalid value.
+ ///
/// State containing the control's .
/// Amount of actuation of the control or -1 if it cannot be determined.
///
- ///
public virtual unsafe float EvaluateMagnitude(void* statePtr)
{
return -1;
}
+ ///
+ /// Read the control's final, processed value from the given buffer and return the value as an object.
+ ///
+ /// Buffer to read the value from.
+ /// Size of in bytes, which must be large enough to store the value.
+ /// The control's value as stored in .
+ ///
+ /// Read the control's final, processed value from the given buffer and return the value as an object.
+ ///
+ /// This method allocates GC memory and should not be used during normal gameplay operation.
+ ///
+ /// is null.
+ /// is smaller than the size of the value to be read.
+ ///
public abstract unsafe object ReadValueFromBufferAsObject(void* buffer, int bufferSize);
///
/// Read the control's final, processed value from the given state and return the value as an object.
///
- ///
+ /// State to read the value for the control from.
/// The control's value as stored in .
///
+ /// Read the control's final, processed value from the given state and return the value as an object.
+ ///
/// This method allocates GC memory and should not be used during normal gameplay operation.
///
/// is null.
@@ -539,7 +572,7 @@ public virtual unsafe float EvaluateMagnitude(void* statePtr)
///
/// Read a value from the given memory and store it as state.
///
- /// Memory containing value.
+ /// Memory containing value, to store into the state.
/// Size of in bytes. Must be at least .
/// State containing the control's . Will receive the state
/// as converted from the given value.
@@ -561,9 +594,9 @@ public virtual unsafe void WriteValueFromBufferIntoState(void* bufferPtr, int bu
///
/// Read a value object and store it as state in the given memory.
///
- /// Value for the control.
+ /// Value for the control to store in the state.
/// State containing the control's . Will receive
- /// the state state as converted from the given value.
+ /// the state as converted from the given value.
///
/// Writing values will NOT apply processors to the given value. This can mean that when reading a value
/// from a control after it has been written to its state, the resulting value differs from what was
@@ -631,6 +664,19 @@ public InputControl TryGetChildControl(string path)
return InputControlPath.TryFindChild(this, path);
}
+ ///
+ /// Try to find a child control matching the given path.
+ ///
+ /// A control path. See .
+ /// The type of control to locate.
+ /// The first direct or indirect child control that matches the given
+ /// or null if no control was found to match.
+ /// is null or empty.
+ /// No control found with the specified type.
+ ///
+ /// Note that if the given path matches multiple child controls, only the first control
+ /// encountered in the search will be returned.
+ ///
public TControl TryGetChildControl(string path)
where TControl : InputControl
{
@@ -649,6 +695,19 @@ public TControl TryGetChildControl(string path)
return controlOfType;
}
+ ///
+ /// Find a child control matching the given path.
+ ///
+ /// A control path. See .
+ /// The first direct or indirect child control that matches the given
+ /// or null if no control was found to match.
+ /// is null or empty.
+ /// No control found with the specified type.
+ /// The control cannot be found.
+ ///
+ /// Note that if the given path matches multiple child controls, only the first control
+ /// encountered in the search will be returned.
+ ///
public InputControl GetChildControl(string path)
{
if (string.IsNullOrEmpty(path))
@@ -661,6 +720,20 @@ public InputControl GetChildControl(string path)
return control;
}
+ ///
+ /// Find a child control matching the given path.
+ ///
+ /// A control path. See .
+ /// The type of control to locate.
+ /// The first direct or indirect child control that matches the given
+ /// or null if no control was found to match.
+ /// is null or empty.
+ /// No control found with the specified type.
+ /// The control cannot be found.
+ ///
+ /// Note that if the given path matches multiple child controls, only the first control
+ /// encountered in the search will be returned.
+ ///
public TControl GetChildControl(string path)
where TControl : InputControl
{
@@ -673,6 +746,12 @@ public TControl GetChildControl(string path)
return controlOfType;
}
+ ///
+ /// Constructor for the InputControl
+ ///
+ ///
+ /// Constructor for the InputControl
+ ///
protected InputControl()
{
// Set defaults for state block setup. Subclasses may override.
@@ -792,6 +871,10 @@ protected void RefreshConfigurationIfNeeded()
///
///
/// The system will call this method automatically whenever a change is made to one of the control's configuration properties.
+ /// This method is only relevant if you are implementing your own devices or new
+ /// types of controls which are fetching configuration data from the devices (such
+ /// as which is fetching display names for individual keys
+ /// from the underlying platform).
/// See .
///
///
@@ -847,13 +930,34 @@ protected virtual void RefreshConfiguration()
}
////TODO: drop protected access
+ ///
+ /// Information about a memory region storing input state.
+ ///
protected internal InputStateBlock m_StateBlock;
////REVIEW: shouldn't these sit on the device?
+ ///
+ /// The state data buffer for the device.
+ ///
+ ///
+ /// The state data buffer for the device.
+ ///
protected internal unsafe void* currentStatePtr => InputStateBuffers.GetFrontBufferForDevice(GetDeviceIndex());
+ ///
+ /// The state data buffer for the device from the previous frame.
+ ///
+ ///
+ /// The state data buffer for the device from the previous frame.
+ ///
protected internal unsafe void* previousFrameStatePtr => InputStateBuffers.GetBackBufferForDevice(GetDeviceIndex());
+ ///
+ /// The default state data buffer
+ ///
+ ///
+ /// Buffer that has state for each device initialized with default values.
+ ///
protected internal unsafe void* defaultStatePtr => InputStateBuffers.s_DefaultStateBuffer;
///
@@ -868,8 +972,9 @@ protected virtual void RefreshConfiguration()
/// that is noise will be masked out whereas all state that isn't will come through unmodified. In other words,
/// any bit that is set in the noise mask indicates that the corresponding bit in the control's state memory
/// is noise.
+ ///
+ /// A control can be marked as .
///
- ///
protected internal unsafe void* noiseMaskPtr => InputStateBuffers.s_NoiseMaskBuffer;
///
@@ -878,7 +983,7 @@ protected virtual void RefreshConfiguration()
///
/// Once a device has been added to the system, its state block will get allocated
/// in the global state buffers and the offset of the device's state block will
- /// get baked into all of the controls on the device. This property always returns
+ /// get baked into all the controls on the device. This property always returns
/// the "unbaked" offset.
///
protected internal uint stateOffsetRelativeToDeviceRoot
@@ -924,13 +1029,15 @@ protected internal uint stateOffsetRelativeToDeviceRoot
internal FourCC m_OptimizedControlDataType;
///
+ /// The type of the state memory associated with the control.
+ ///
+ ///
/// For some types of control you can safely read/write state memory directly
/// which is much faster than calling ReadUnprocessedValueFromState/WriteValueIntoState.
/// This method returns a type that you can use for reading/writing the control directly,
- /// or it returns InputStateBlock.kFormatInvalid if it's not possible for this type of control.
- ///
- ///
- /// For example, AxisControl might be a "float" in state memory, and if no processing is applied during reading (e.g. no invert/scale/etc),
+ /// or it returns if it's not possible for this type of control.
+ ///
+ /// For example, AxisControl might be a "float" in state memory, and if no processing is applied during reading (e.g. no invert/scale/etc),
/// then you could read it as float in memory directly without calling ReadUnprocessedValueFromState, which is faster.
/// Additionally, if you have a Vector3Control which uses 3 AxisControls as consecutive floats in memory,
/// you can cast the Vector3Control state memory directly to Vector3 without calling ReadUnprocessedValueFromState on x/y/z axes.
@@ -942,18 +1049,33 @@ protected internal uint stateOffsetRelativeToDeviceRoot
public FourCC optimizedControlDataType => m_OptimizedControlDataType;
///
- /// Calculates and returns a optimized data type that can represent a control's value in memory directly.
+ /// Calculates and returns an optimized data type that can represent a control's value in memory directly.
+ ///
+ ///
/// The value then is cached in .
/// This method is for internal use only, you should not call this from your own code.
- ///
+ ///
+ ///
+ /// An optimized data type that can represent a control's value in memory directly.
+ ///
protected virtual FourCC CalculateOptimizedControlDataType()
{
return InputStateBlock.kFormatInvalid;
}
///
- /// Apply built-in parameters changes (e.g. , others), recompute for impacted controls and clear cached value.
+ /// Apply built-in parameters changes.
///
+ ///
+ /// Apply built-in parameters changes (e.g. , others).
+ /// Recompute for impacted controls and clear cached value
+ ///
+ ///
+ ///
+ /// Gamepad.all[0].leftTrigger.WriteValueIntoState(0.5f, Gamepad.all[0].currentStatePtr);
+ /// Gamepad.all[0].ApplyParameterChanges();
+ ///
+ ///
public void ApplyParameterChanges()
{
// First we go through all children of our own hierarchy
@@ -1194,14 +1316,16 @@ internal virtual IEnumerable
///
public TValue ReadValue()
@@ -1378,6 +1502,16 @@ public TValue ReadDefaultValue()
}
}
+ ///
+ /// Get the control's default value.
+ ///
+ /// State containing the control's .
+ /// The control's default value.
+ ///
+ /// This is not necessarily equivalent to default(TValue). A control's default value is determined
+ /// by reading its value from the default state () which in turn
+ /// is determined from settings in the control's registered layout ().
+ ///
public unsafe TValue ReadValueFromState(void* statePtr)
{
if (statePtr == null)
@@ -1413,11 +1547,28 @@ public unsafe TValue ReadUnprocessedValueFromStateWithCaching(void* statePtr)
return statePtr == currentStatePtr ? unprocessedValue : ReadUnprocessedValueFromState(statePtr);
}
+ ///
+ /// Read value from control
+ ///
+ /// The controls current value.
+ ///
+ /// This is the locally cached value. Use to get the uncached version.
+ ///
+ ///
public TValue ReadUnprocessedValue()
{
return unprocessedValue;
}
+ ///
+ /// Read value from provided .
+ ///
+ /// State pointer to read from.
+ /// The controls current value.
+ ///
+ /// Read value from provided without any caching.
+ ///
+ ///
public abstract unsafe TValue ReadUnprocessedValueFromState(void* statePtr);
///
@@ -1445,6 +1596,7 @@ public override unsafe void ReadValueFromStateIntoBuffer(void* statePtr, void* b
UnsafeUtility.MemCpy(bufferPtr, valuePtr, numBytes);
}
+ ///
public override unsafe void WriteValueFromBufferIntoState(void* bufferPtr, int bufferSize, void* statePtr)
{
if (bufferPtr == null)
@@ -1482,6 +1634,20 @@ public override unsafe void WriteValueFromObjectIntoState(object value, void* st
WriteValueIntoState(valueOfType, statePtr);
}
+ ///
+ /// Write a value into state at the given memory.
+ ///
+ /// Value for the control to store in the state.
+ /// State containing the control's . Will receive
+ /// the state as converted from the given value.
+ ///
+ /// Writing values will NOT apply processors to the given value. This can mean that when reading a value
+ /// from a control after it has been written to its state, the resulting value differs from what was
+ /// written.
+ ///
+ /// The control does not support writing. This is the case, for
+ /// example, that compute values (such as the magnitude of a vector).
+ ///
public virtual unsafe void WriteValueIntoState(TValue value, void* statePtr)
{
////REVIEW: should we be able to even tell from layouts which controls support writing and which don't?
@@ -1520,6 +1686,12 @@ private static unsafe bool CompareValue(ref TValue firstValue, ref TValue second
return UnsafeUtility.MemCmp(firstValuePtr, secondValuePtr, UnsafeUtility.SizeOf()) != 0;
}
+ ///
+ /// Compared values in state buffers.
+ ///
+ /// The first state buffer to read value from.
+ /// The second state buffer to read value from.
+ /// True if the buffer values match. False if they differ.
public override unsafe bool CompareValue(void* firstStatePtr, void* secondStatePtr)
{
////REVIEW: should we first compare state here? if there's no change in state, there can be no change in value and we can skip the rest
@@ -1530,6 +1702,14 @@ public override unsafe bool CompareValue(void* firstStatePtr, void* secondStateP
return CompareValue(ref firstValue, ref secondValue);
}
+ ///
+ /// Applies all control processors to the passed value.
+ ///
+ /// value to run processors on.
+ /// The processed value.
+ ///
+ /// Applies all control processors to the passed value.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TValue ProcessValue(TValue value)
{
@@ -1540,7 +1720,7 @@ public TValue ProcessValue(TValue value)
///
/// Applies all control processors to the passed value.
///
- ///
+ /// value to run processors on.
///
/// Use this overload when your state struct is large to avoid creating copies of the state.
///
@@ -1622,6 +1802,7 @@ internal override IEnumerable