using UnityEngine.InputSystem.Layouts; using UnityEngine.InputSystem.LowLevel; using UnityEngine.InputSystem.Processors; using UnityEngine.InputSystem.Utilities; ////TODO: make sure that alterations made to InputSystem.settings in play mode do not leak out into edit mode or the asset ////TODO: handle case of supportFixedUpdates and supportDynamicUpdates both being set to false; should it be an enum? ////TODO: figure out how this gets into a build ////TODO: allow setting up single- and multi-user configs for the project ////TODO: allow enabling/disabling plugins ////REVIEW: should the project settings include a list of action assets to use? (or to force into a build) ////REVIEW: add extra option to enable late-updates? ////REVIEW: put default sensor sampling frequency here? ////REVIEW: put default gamepad polling frequency here? namespace UnityEngine.InputSystem { /// /// Project-wide input settings. /// /// /// Several aspects of the input system can be customized to tailor how the system functions to the /// specific needs of a project. These settings are collected in this class. There is one global /// settings object active at any one time. It can be accessed and set through . /// /// Changing a setting on the object takes effect immediately. It also triggers the /// callback. /// /// /// public class InputSettings : ScriptableObject { /// /// Determine how the input system updates, i.e. processes pending input events. /// /// When to run input updates. /// /// By default, input updates will automatically be triggered as part of the player loop. /// If updateMode is set to /// (the default), then right at the beginning of a dynamic update (i.e. before all /// MonoBehaviour.Update methods are called), input is processed. And if updateMode /// is set to , then right at the beginning /// of each fixed update (i.e. before all MonoBehaviour.FixedUpdate methods are /// called), input is processed. /// /// Additionally, if there are devices that need updates right before rendering (see ), an extra update will be run right before /// rendering. This special update will only consume input on devices that have /// set to true. /// /// You can run updates manually using . Doing so /// outside of tests is only recommended, however, if updateMode is set to /// (in which case it is actually required /// for input to be processed at all). /// /// Note that in the editor, input updates will also run before each editor update /// (i.e. as part of EditorApplication.update). Player and editor input state /// are kept separate, though, so any input consumed in editor updates will not be visible /// in player updates and vice versa. /// /// public UpdateMode updateMode { get => m_UpdateMode; set { if (m_UpdateMode == value) return; m_UpdateMode = value; OnChange(); } } /// /// If true, sensors that deliver rotation values on handheld devices will automatically adjust /// rotations when the screen orientation changes. /// /// /// This is enabled by default. /// /// If enabled, rotation values will be rotated around Z. In , values /// remain unchanged. In , they will be rotated by 180 degrees. /// In by 90 degrees, and in /// by 270 degrees. /// /// Sensors affected by this setting are , , and . /// /// public bool compensateForScreenOrientation { get => m_CompensateForScreenOrientation; set { if (m_CompensateForScreenOrientation == value) return; m_CompensateForScreenOrientation = value; OnChange(); } } /// /// Whether to not make a device .current (see ) /// when there is only noise in the input. /// /// Whether to check input on devices for noise. /// /// This is disabled by default. /// /// When toggled on, this property adds extra processing every time input is /// received on a device that is considered noisy. These devices are those that /// have at least one control that is marked as . /// A good example is the PS4 controller which has a gyroscope sensor built into /// the device. Whereas sticks and buttons on the device require user interaction /// to produce non-default values, the gyro will produce varying values even if /// the device just sits there without user interaction. /// /// Without noise filtering, a PS4 controller will thus continually make itself /// current as it will send a continuous stream of input even when not actively /// used by the player. By toggling this property on, each input event will be /// run through a noise mask. Only if state has changed outside of memory areas /// marked as noise will the input be considered valid user interaction and the /// device will be made current. Note that in this process, the system does /// not determine whether non-noisy controls on the device have actually /// changed value. All the system establishes is whether such controls have changed /// state. However, processing such as for deadzones may cause values /// to not effectively change even though the non-noisy state of the device has /// changed. /// /// /// public bool filterNoiseOnCurrent { get => m_FilterNoiseOnCurrent; set { if (m_FilterNoiseOnCurrent == value) return; m_FilterNoiseOnCurrent = value; OnChange(); } } /// /// Default value used when nothing is set explicitly on /// or . /// /// Default lower limit for deadzones. /// /// "Deadzones" refer to limits established for the range of values accepted as input /// on a control. If the value for the control falls outside the range, i.e. below the /// given minimum or above the given maximum, the value is clamped to the respective /// limit. /// /// This property configures the default lower bound of the value range. /// /// Note that deadzones will by default re-normalize values after clamping. This means that /// inputs at the lower and upper end are dropped and that the range in-between is re-normalized /// to [0..1]. /// /// Note that deadzones preserve the sign of inputs. This means that both the upper and /// the lower deadzone bound extend to both the positive and the negative range. For example, /// a deadzone min of 0.1 will clamp values between -0.1 and +0.1. /// /// The most common example of where deadzones are used are the sticks on gamepads, i.e. /// and . Sticks will /// usually be wobbly to some extent (just how wobbly varies greatly between different /// types of controllers -- which means that often deadzones need to be configured on a /// per-device type basis). Using deadzones, stick motion at the extreme ends of the spectrum /// can be filtered out and noise in these areas can effectively be eliminated this way. /// /// The default value for this property is 0.125. /// /// /// public float defaultDeadzoneMin { get => m_DefaultDeadzoneMin; set { if (m_DefaultDeadzoneMin == value) return; m_DefaultDeadzoneMin = value; OnChange(); } } /// /// Default value used when nothing is set explicitly on /// or . /// /// Default upper limit for deadzones. /// /// "Deadzones" refer to limits established for the range of values accepted as input /// on a control. If the value for the control falls outside the range, i.e. below the /// given minimum or above the given maximum, the value is clamped to the respective /// limit. /// /// This property configures the default upper bound of the value range. /// /// Note that deadzones will by default re-normalize values after clamping. This means that /// inputs at the lower and upper end are dropped and that the range in-between is re-normalized /// to [0..1]. /// /// Note that deadzones preserve the sign of inputs. This means that both the upper and /// the lower deadzone bound extend to both the positive and the negative range. For example, /// a deadzone max of 0.95 will clamp values of >0.95 and <-0.95. /// /// The most common example of where deadzones are used are the sticks on gamepads, i.e. /// and . Sticks will /// usually be wobbly to some extent (just how wobbly varies greatly between different /// types of controllers -- which means that often deadzones need to be configured on a /// per-device type basis). Using deadzones, stick motion at the extreme ends of the spectrum /// can be filtered out and noise in these areas can effectively be eliminated this way. /// /// The default value for this property is 0.925. /// /// /// public float defaultDeadzoneMax { get => m_DefaultDeadzoneMax; set { if (m_DefaultDeadzoneMax == value) return; m_DefaultDeadzoneMax = value; OnChange(); } } /// /// The default value threshold for when a button is considered pressed. Used if /// no explicit thresholds are set on parameters such as /// or . /// /// Default button press threshold. /// /// In the input system, each button constitutes a full floating-point value. Pure /// toggle buttons, such as for example, will simply /// alternate between 0 (not pressed) and 1 (pressed). However, buttons may also have /// ranges, such as for example. When used in a context /// where a clear distinction between pressed and not pressed is required, we need a value /// beyond which we consider the button pressed. /// /// By setting this property, the default value for this can be configured. If a button /// has a value equal to or greater than the button press point, it is considered pressed. /// /// The default value is 0.5. /// /// Lowering the button press point will make triggers feel more like hair-triggers (akin /// to using the hair-trigger feature on Xbox Elite controllers). However, it may make using /// the directional buttons (i.e. etc) be fickle as /// solely moving in only one direction with sticks isn't easy. To counteract that, the button /// press points on the stick buttons can be raised. /// /// Another solution is to simply lower the press points on the triggers specifically. /// /// /// /// InputSystem.RegisterLayoutOverride(@" /// { /// ""name"" : ""HairTriggers"", /// ""extend"" : ""Gamepad"", /// ""controls"" [ /// { ""name"" : ""leftTrigger"", ""parameters"" : ""pressPoint=0.1"" }, /// { ""name"" : ""rightTrigger"", ""parameters"" : ""pressPoint=0.1"" } /// ] /// } /// "); /// /// /// /// /// /// /// /// /// public float defaultButtonPressPoint { get => m_DefaultButtonPressPoint; set { if (m_DefaultButtonPressPoint == value) return; m_DefaultButtonPressPoint = value; OnChange(); } } /// /// Default time (in seconds) within which a press and release has to occur for it /// to be registered as a "tap". /// /// Default upper limit on press durations for them to register as taps. /// /// A tap is considered as a quick press-and-release on a button-like input control. /// This property determines just how quick the press-and-release has to be, i.e. what /// the maximum time is that can elapse between the button being pressed and released /// again. If the delay between press and release is greater than this time, the /// input does not qualify as a tap. /// /// The default tap time is 0.2 seconds. /// /// public float defaultTapTime { get => m_DefaultTapTime; set { if (m_DefaultTapTime == value) return; m_DefaultTapTime = value; OnChange(); } } public float defaultSlowTapTime { get => m_DefaultSlowTapTime; set { if (m_DefaultSlowTapTime == value) return; m_DefaultSlowTapTime = value; OnChange(); } } public float defaultHoldTime { get => m_DefaultHoldTime; set { if (m_DefaultHoldTime == value) return; m_DefaultHoldTime = value; OnChange(); } } public float tapRadius { get => m_TapRadius; set { if (m_TapRadius == value) return; m_TapRadius = value; OnChange(); } } public float multiTapDelayTime { get => m_MultiTapDelayTime; set { if (m_MultiTapDelayTime == value) return; m_MultiTapDelayTime = value; OnChange(); } } /// /// List of device layouts used by the project. /// /// /// This would usually be one of the high-level abstract device layouts. For example, for /// a game that supports touch, gamepad, and keyboard&mouse, the list would be /// { "Touchscreen", "Gamepad", "Mouse", "Keyboard" }. However, nothing prevents the /// the user from adding something a lot more specific. A game that can only be played /// with a DualShock controller could make this list just be { "DualShockGamepad" }, /// for example. /// /// In the editor, we use the information to filter what we display to the user by automatically /// filtering out irrelevant controls in the control picker and such. /// /// The information is also used when a new device is discovered. If the device is not listed /// as supported by the project, it is ignored. /// /// The list is empty by default. An empty list indicates that no restrictions are placed on what /// devices are supported. In this editor, this means that all possible devices and controls are /// shown. /// /// public ReadOnlyArray supportedDevices { get => new ReadOnlyArray(m_SupportedDevices); set { // Detect if there was a change. if (supportedDevices.Count == value.Count) { var hasChanged = false; for (var i = 0; i < supportedDevices.Count; ++i) if (m_SupportedDevices[i] != value[i]) { hasChanged = true; break; } if (!hasChanged) return; } m_SupportedDevices = value.ToArray(); OnChange(); } } [Tooltip("Determine which type of devices are used by the application. By default, this is empty meaning that all devices recognized " + "by Unity will be used. Restricting the set of supported devices will make only those devices appear in the input system.")] [SerializeField] private string[] m_SupportedDevices; [Tooltip("Determine when Unity processes events. By default, accumulated input events are flushed out before each fixed update and " + "before each dynamic update. This setting can be used to restrict event processing to only where the application needs it.")] [SerializeField] private UpdateMode m_UpdateMode = UpdateMode.ProcessEventsInDynamicUpdate; [SerializeField] private bool m_CompensateForScreenOrientation = true; [SerializeField] private bool m_FilterNoiseOnCurrent = false; [SerializeField] private float m_DefaultDeadzoneMin = 0.125f; [SerializeField] private float m_DefaultDeadzoneMax = 0.925f; // A setting of 0.5 seems to roughly be what games generally use on the gamepad triggers. // Having a higher value here also obsoletes the need for custom press points on stick buttons // (the up/down/left/right ones). [SerializeField] private float m_DefaultButtonPressPoint = 0.5f; [SerializeField] private float m_DefaultTapTime = 0.2f; [SerializeField] private float m_DefaultSlowTapTime = 0.5f; [SerializeField] private float m_DefaultHoldTime = 0.4f; [SerializeField] private float m_TapRadius = 5; [SerializeField] private float m_MultiTapDelayTime = 0.75f; internal void OnChange() { if (InputSystem.settings == this) InputSystem.s_Manager.ApplySettings(); } internal const int s_OldUnsupportedFixedAndDynamicUpdateSetting = 0; /// /// How the input system should update. /// /// /// By default, the input system will run event processing as part of the player loop. In the default configuration, /// the processing will happens once before every every dynamic update (), i.e. /// is the default behavior. /// /// There are two types of updates not governed by UpdateMode. One is which /// will always be enabled in the editor and govern input updates for s in /// sync to . /// /// The other update type is . This type of update is enabled and disabled /// automatically in response to whether devices are present requiring this type of update (). This update does not consume extra state. /// /// /// /// /// public enum UpdateMode { // Removed: ProcessEventsInBothFixedAndDynamicUpdate=0 /// /// Automatically run input updates right before every . /// /// /// In this mode, no processing happens specifically for fixed updates. Querying input state in /// will result in errors being logged in the editor and in /// development builds. In release player builds, the value of the dynamic update state is returned. /// ProcessEventsInDynamicUpdate = 1, /// /// Automatically input run updates right before every . /// /// /// In this mode, no processing happens specifically for dynamic updates. Querying input state in /// will result in errors being logged in the editor and in /// development builds. In release player builds, the value of the fixed update state is returned. /// ProcessEventsInFixedUpdate, /// /// Do not run updates automatically. In this mode, must be called /// manually to update input. /// /// /// This mode is most useful for placing input updates in the frame explicitly at an exact location. /// /// Note that failing to call may result in a lot of events /// accumulating or some input getting lost. /// ProcessEventsManually, } } }