diff --git a/Assets/Tests/InputSystem/CoreTests_Devices.cs b/Assets/Tests/InputSystem/CoreTests_Devices.cs index ed90efe605..33a31980dc 100644 --- a/Assets/Tests/InputSystem/CoreTests_Devices.cs +++ b/Assets/Tests/InputSystem/CoreTests_Devices.cs @@ -3818,6 +3818,145 @@ public void Devices_CanGetAccelerometerReading() Assert.That(Accelerometer.current, Is.SameAs(accelerometer)); } + [Test] + [Category("Devices")] + public void Devices_CanGetLocationSensorReading() + { + var location = InputSystem.AddDevice(); + InputSystem.EnableDevice(location); // Sensors start disabled. + InputSystem.QueueStateEvent(location, new LocationState + { + latitude = 59.3293f, + longitude = 18.0686f, + altitude = 28.0f, + horizontalAccuracy = 5.0f, + verticalAccuracy = 8.0f, + timestamp = 1_700_000_000.0 + }); + InputSystem.Update(); + + Assert.That(location.latitude.ReadValue(), Is.EqualTo(59.3293f).Within(1e-4)); + Assert.That(location.longitude.ReadValue(), Is.EqualTo(18.0686f).Within(1e-4)); + Assert.That(location.altitude.ReadValue(), Is.EqualTo(28.0f).Within(1e-4)); + Assert.That(location.horizontalAccuracy.ReadValue(), Is.EqualTo(5.0f).Within(1e-4)); + Assert.That(location.verticalAccuracy.ReadValue(), Is.EqualTo(8.0f).Within(1e-4)); + Assert.That(location.timestamp.ReadValue(), Is.EqualTo(1_700_000_000.0).Within(1e-6)); + Assert.That(LocationSensor.current, Is.SameAs(location)); + } + + [Test] + [Category("Devices")] + public unsafe void Devices_CanQueryLocationSensorStatus() + { + var location = InputSystem.AddDevice(); + runtime.SetDeviceCommandCallback(location.deviceId, + (id, commandPtr) => + { + if (commandPtr->type == QueryLocationStatusCommand.Type) + { + ((QueryLocationStatusCommand*)commandPtr)->status = (int)LocationServiceStatus.Running; + return InputDeviceCommand.GenericSuccess; + } + + return InputDeviceCommand.GenericFailure; + }); + + Assert.That(location.status, Is.EqualTo(LocationServiceStatus.Running)); + } + + [Test] + [Category("Devices")] + public unsafe void Devices_CanConfigureLocationSensor() + { + var location = InputSystem.AddDevice(); + + // The callback below is registered after AddDevice, so OnAdded's seed ConfigureLocationCommand + // (the 10f/10f InputSettings defaults) fires before any callback exists and is dropped. + // The 5f/2f value-gate below distinguishes our explicit Configure() call from those defaults. + var received = false; + runtime.SetDeviceCommandCallback(location.deviceId, + (id, commandPtr) => + { + if (commandPtr->type == ConfigureLocationCommand.Type) + { + var command = (ConfigureLocationCommand*)commandPtr; + if (Mathf.Approximately(command->desiredAccuracyInMeters, 5f) && + Mathf.Approximately(command->updateDistanceInMeters, 2f)) + received = true; + return InputDeviceCommand.GenericSuccess; + } + + return InputDeviceCommand.GenericFailure; + }); + + location.Configure(5f, 2f); + + Assert.That(received, Is.True); + } + + [Test] + [Category("Devices")] + public unsafe void Devices_CanQueryLocationSensorIsEnabledByUser() + { + var location = InputSystem.AddDevice(); + runtime.SetDeviceCommandCallback(location.deviceId, + (id, commandPtr) => + { + if (commandPtr->type == QueryLocationEnabledByUserCommand.Type) + { + ((QueryLocationEnabledByUserCommand*)commandPtr)->enabledByUser = true; + return InputDeviceCommand.GenericSuccess; + } + + return InputDeviceCommand.GenericFailure; + }); + + Assert.That(location.isEnabledByUser, Is.True); + } + + [Test] + [Category("Devices")] + public void Devices_LocationSensorDegradesWhenNoNativeHandler() + { + var location = InputSystem.AddDevice(); + + // No command callback is installed, so both queries fall through to the + // "no native impl (editor/desktop)" degradation paths. + Assert.That(location.status, Is.EqualTo(LocationServiceStatus.Stopped)); + Assert.That(location.isEnabledByUser, Is.False); + } + + [Test] + [Category("Devices")] + public unsafe void Devices_CanResetLocationConfig() + { + InputSystem.settings.locationAccuracy = 33f; + InputSystem.settings.locationDistanceThreshold = 7f; + + var location = InputSystem.AddDevice(); + + var lastAccuracy = 0f; + var lastDistanceThreshold = 0f; + runtime.SetDeviceCommandCallback(location.deviceId, + (id, commandPtr) => + { + if (commandPtr->type == ConfigureLocationCommand.Type) + { + var command = (ConfigureLocationCommand*)commandPtr; + lastAccuracy = command->desiredAccuracyInMeters; + lastDistanceThreshold = command->updateDistanceInMeters; + return InputDeviceCommand.GenericSuccess; + } + + return InputDeviceCommand.GenericFailure; + }); + + location.ResetConfiguration(); + + Assert.That(lastAccuracy, Is.EqualTo(33f).Within(1e-4)); + Assert.That(lastDistanceThreshold, Is.EqualTo(7f).Within(1e-4)); + } + [Test] [Category("Devices")] public void Devices_CanGetGyroReading() diff --git a/Packages/com.unity.inputsystem/Documentation~/corresponding-old-new-api.md b/Packages/com.unity.inputsystem/Documentation~/corresponding-old-new-api.md index dcad91390f..e1a71536df 100644 --- a/Packages/com.unity.inputsystem/Documentation~/corresponding-old-new-api.md +++ b/Packages/com.unity.inputsystem/Documentation~/corresponding-old-new-api.md @@ -115,5 +115,5 @@ Note: [`UnityEngine.TouchScreenKeyboard`](https://docs.unity3d.com/ScriptReferen [`Input.gyro.rotationRateUnbiased`](https://docs.unity3d.com/ScriptReference/Gyroscope-rotationRateUnbiased.html)|No corresponding API yet. [`Input.gyro.updateInterval`](https://docs.unity3d.com/ScriptReference/Gyroscope-updateInterval.html)|[`Sensor.samplingFrequency`](xref:UnityEngine.InputSystem.Sensor)
Example:
`Gyroscope.current.samplingFrequency = 1.0f / updateInterval;`

__Notes__:
[`samplingFrequency`](xref:UnityEngine.InputSystem.Sensor) is in Hz, not in seconds as [`updateInterval`](https://docs.unity3d.com/ScriptReference/Gyroscope-updateInterval.html), so you need to divide 1 by the value.

The new Input System replaces `UnityEngine.Gyroscope` with multiple separate sensor devices. Substitute [`Gyroscope`](xref:UnityEngine.InputSystem.Gyroscope) with other sensors in the sample as needed. See the notes for `Input.gyro` above for details. [`Input.gyro.userAcceleration`](https://docs.unity3d.com/ScriptReference/Gyroscope-userAcceleration.html)|[`LinearAccelerationSensor.current.acceleration.ReadValue()`](xref:UnityEngine.InputSystem.LinearAccelerationSensor) -[`Input.location`](https://docs.unity3d.com/ScriptReference/Input-location.html)|No corresponding API yet. +[`Input.location`](https://docs.unity3d.com/ScriptReference/Input-location.html)|[`LocationSensor`](xref:UnityEngine.InputSystem.LocationSensor).
Start/Stop:
`InputSystem.EnableDevice(LocationSensor.current);`
`InputSystem.DisableDevice(LocationSensor.current);`
Read the last fix from the controls, for example `LocationSensor.current.latitude.ReadValue()` (also `longitude`, `altitude`, `horizontalAccuracy`, `verticalAccuracy`, `timestamp`).
Query lifecycle and permission with [`LocationSensor.status`](xref:UnityEngine.InputSystem.LocationSensor) and [`LocationSensor.isEnabledByUser`](xref:UnityEngine.InputSystem.LocationSensor).
Set the requested accuracy and update-distance with `LocationSensor.current.Configure(accuracyInMeters, updateDistanceInMeters)`, or `ResetConfiguration()` to revert to the project defaults [`InputSettings.locationAccuracy`](xref:UnityEngine.InputSystem.InputSettings) and [`InputSettings.locationDistanceThreshold`](xref:UnityEngine.InputSystem.InputSettings). [`Input.GetAccelerationEvent`](https://docs.unity3d.com/ScriptReference/Input.GetAccelerationEvent.html)|See notes for `Input.accelerationEvents` above. diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs index 575d73c9f5..84ef946513 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs @@ -128,6 +128,8 @@ public override void OnGUI(string searchContext) EditorGUILayout.Space(); EditorGUILayout.PropertyField(m_CompensateForScreenOrientation, m_CompensateForScreenOrientationContent); + EditorGUILayout.PropertyField(m_LocationAccuracy, m_LocationAccuracyContent); + EditorGUILayout.PropertyField(m_LocationDistanceThreshold, m_LocationDistanceThresholdContent); // NOTE: We do NOT make showing this one conditional on whether runInBackground is actually set in the // player settings as regardless of whether it's on or not, Unity will force it on in standalone @@ -302,6 +304,8 @@ private void InitializeWithCurrentSettings() m_UpdateMode = m_SettingsObject.FindProperty("m_UpdateMode"); m_ScrollDeltaBehavior = m_SettingsObject.FindProperty("m_ScrollDeltaBehavior"); m_CompensateForScreenOrientation = m_SettingsObject.FindProperty("m_CompensateForScreenOrientation"); + m_LocationAccuracy = m_SettingsObject.FindProperty("m_LocationAccuracy"); + m_LocationDistanceThreshold = m_SettingsObject.FindProperty("m_LocationDistanceThreshold"); m_BackgroundBehavior = m_SettingsObject.FindProperty("m_BackgroundBehavior"); m_EditorInputBehaviorInPlayMode = m_SettingsObject.FindProperty("m_EditorInputBehaviorInPlayMode"); m_DefaultDeadzoneMin = m_SettingsObject.FindProperty("m_DefaultDeadzoneMin"); @@ -321,6 +325,8 @@ private void InitializeWithCurrentSettings() m_ScrollDeltaBehaviorContent = new GUIContent("Scroll Delta Behavior", "Controls whether the value returned by the Scroll Wheel Delta is normalized (to be uniform across all platforms), or returns the non-normalized platform-specific range which can vary between platforms."); #endif m_CompensateForScreenOrientationContent = new GUIContent("Compensate Orientation", "Whether sensor input on mobile devices should be transformed to be relative to the current device orientation."); + m_LocationAccuracyContent = new GUIContent("Location Accuracy", "Default desired accuracy of LocationSensor updates, in meters. The accuracy achieved is hardware and platform-dependent, and a finer accuracy can increase power use."); + m_LocationDistanceThresholdContent = new GUIContent("Location Distance Threshold", "Default minimum distance, in meters, the device must move before LocationSensor reports an update. A larger threshold reports updates less often, which can lower power use."); m_BackgroundBehaviorContent = new GUIContent("Background Behavior", "If runInBackground is true (and in standalone *development* players and the editor), " + "determines what happens to InputDevices and events when the application moves in and out of running in the foreground.\n\n" + "'Reset And Disable Non-Background Devices' soft-resets and disables devices that cannot run in the background while the application does not have focus. Devices " @@ -446,6 +452,8 @@ private static string[] FindInputSettingsInProject() [NonSerialized] private SerializedProperty m_UpdateMode; [NonSerialized] private SerializedProperty m_ScrollDeltaBehavior; [NonSerialized] private SerializedProperty m_CompensateForScreenOrientation; + [NonSerialized] private SerializedProperty m_LocationAccuracy; + [NonSerialized] private SerializedProperty m_LocationDistanceThreshold; [NonSerialized] private SerializedProperty m_BackgroundBehavior; [NonSerialized] private SerializedProperty m_EditorInputBehaviorInPlayMode; [NonSerialized] private SerializedProperty m_DefaultDeadzoneMin; @@ -473,6 +481,8 @@ private static string[] FindInputSettingsInProject() private GUIContent m_ScrollDeltaBehaviorContent; #endif private GUIContent m_CompensateForScreenOrientationContent; + private GUIContent m_LocationAccuracyContent; + private GUIContent m_LocationDistanceThresholdContent; private GUIContent m_BackgroundBehaviorContent; private GUIContent m_EditorInputBehaviorInPlayModeContent; private GUIContent m_DefaultDeadzoneMinContent; diff --git a/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/ConfigureLocationCommand.cs b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/ConfigureLocationCommand.cs new file mode 100644 index 0000000000..fd3bb0d20c --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/ConfigureLocationCommand.cs @@ -0,0 +1,37 @@ +using System.Runtime.InteropServices; +using UnityEngine.InputSystem.Utilities; + +namespace UnityEngine.InputSystem.LowLevel +{ + /// + /// Command to set the desired accuracy and update-distance threshold of a . + /// + [StructLayout(LayoutKind.Explicit, Size = kSize)] + public struct ConfigureLocationCommand : IInputDeviceCommandInfo + { + public static FourCC Type => new FourCC('L', 'C', 'F', 'G'); + + internal const int kSize = InputDeviceCommand.kBaseCommandSize + sizeof(float) * 2; + + [FieldOffset(0)] + public InputDeviceCommand baseCommand; + + [FieldOffset(InputDeviceCommand.kBaseCommandSize)] + public float desiredAccuracyInMeters; + + [FieldOffset(InputDeviceCommand.kBaseCommandSize + sizeof(float))] + public float updateDistanceInMeters; + + public FourCC typeStatic => Type; + + public static ConfigureLocationCommand Create(float desiredAccuracyInMeters, float updateDistanceInMeters) + { + return new ConfigureLocationCommand + { + baseCommand = new InputDeviceCommand(Type, kSize), + desiredAccuracyInMeters = desiredAccuracyInMeters, + updateDistanceInMeters = updateDistanceInMeters + }; + } + } +} diff --git a/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/ConfigureLocationCommand.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/ConfigureLocationCommand.cs.meta new file mode 100644 index 0000000000..82326bf220 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/ConfigureLocationCommand.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c34cf3d871008934dbec8c2f78fd2b44 \ No newline at end of file diff --git a/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationEnabledByUserCommand.cs b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationEnabledByUserCommand.cs new file mode 100644 index 0000000000..1d6a7227e5 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationEnabledByUserCommand.cs @@ -0,0 +1,32 @@ +using System.Runtime.InteropServices; +using UnityEngine.InputSystem.Utilities; + +namespace UnityEngine.InputSystem.LowLevel +{ + /// + /// Command to query whether the user has granted OS-level permission for a to access location data. + /// + [StructLayout(LayoutKind.Explicit, Size = kSize)] + public struct QueryLocationEnabledByUserCommand : IInputDeviceCommandInfo + { + public static FourCC Type => new FourCC('L', 'U', 'S', 'R'); + + internal const int kSize = InputDeviceCommand.kBaseCommandSize + sizeof(bool); + + [FieldOffset(0)] + public InputDeviceCommand baseCommand; + + [FieldOffset(InputDeviceCommand.kBaseCommandSize)] + public bool enabledByUser; + + public FourCC typeStatic => Type; + + public static QueryLocationEnabledByUserCommand Create() + { + return new QueryLocationEnabledByUserCommand + { + baseCommand = new InputDeviceCommand(Type, kSize) + }; + } + } +} diff --git a/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationEnabledByUserCommand.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationEnabledByUserCommand.cs.meta new file mode 100644 index 0000000000..591688ebce --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationEnabledByUserCommand.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c424603c48a383a4db10641fb4c153a0 \ No newline at end of file diff --git a/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationStatusCommand.cs b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationStatusCommand.cs new file mode 100644 index 0000000000..573eeb61b7 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationStatusCommand.cs @@ -0,0 +1,33 @@ +using System.Runtime.InteropServices; +using UnityEngine.InputSystem.Utilities; + +namespace UnityEngine.InputSystem.LowLevel +{ + /// + /// Command to query the current status of a 's underlying platform location service. + /// + [StructLayout(LayoutKind.Explicit, Size = kSize)] + public struct QueryLocationStatusCommand : IInputDeviceCommandInfo + { + public static FourCC Type => new FourCC('L', 'S', 'T', 'A'); + + internal const int kSize = InputDeviceCommand.kBaseCommandSize + sizeof(int); + + [FieldOffset(0)] + public InputDeviceCommand baseCommand; + + // 0 Stopped, 1 Initializing, 2 Running, 3 Failed (matches UnityEngine.LocationServiceStatus). + [FieldOffset(InputDeviceCommand.kBaseCommandSize)] + public int status; + + public FourCC typeStatic => Type; + + public static QueryLocationStatusCommand Create() + { + return new QueryLocationStatusCommand + { + baseCommand = new InputDeviceCommand(Type, kSize) + }; + } + } +} diff --git a/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationStatusCommand.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationStatusCommand.cs.meta new file mode 100644 index 0000000000..aea4c69174 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Commands/QueryLocationStatusCommand.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 6df2a82c47c50a448b780dac53477379 \ No newline at end of file diff --git a/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Sensor.cs b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Sensor.cs index c4cd9c952d..f74bb52f7d 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Sensor.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Runtime/Devices/Sensor.cs @@ -60,6 +60,30 @@ internal struct LinearAccelerationState : IInputStateTypeInfo public FourCC format => kFormat; } + + /// + /// Low-level input state for . + /// + internal struct LocationState : IInputStateTypeInfo + { + public static FourCC kFormat => new FourCC('L', 'O', 'C', ' '); + + // Order matches native LocationInfo (timestamp first). Do not reorder. + [InputControl(displayName = "Timestamp", layout = "Double")] + public double timestamp; + [InputControl(displayName = "Latitude", layout = "Axis", noisy = true)] + public float latitude; + [InputControl(displayName = "Longitude", layout = "Axis", noisy = true)] + public float longitude; + [InputControl(displayName = "Altitude", layout = "Axis", noisy = true)] + public float altitude; + [InputControl(displayName = "Horizontal Accuracy", layout = "Axis", noisy = true)] + public float horizontalAccuracy; + [InputControl(displayName = "Vertical Accuracy", layout = "Axis", noisy = true)] + public float verticalAccuracy; + + public FourCC format => kFormat; + } } namespace UnityEngine.InputSystem @@ -694,4 +718,158 @@ protected override void FinishSetup() base.FinishSetup(); } } + + /// + /// Input device representing a GPS location sensor. + /// + /// + /// A location sensor reports the device's geographic position (, + /// , ). + /// After enabling it with , the location service may take several + /// seconds to acquire valid data, so readings are only valid once reaches + /// . Accessing location requires the user to have + /// granted permission (). + /// + [InputControlLayout(stateType = typeof(LocationState), displayName = "Location")] + public class LocationSensor : Sensor + { + /// + /// Latitude in degrees. + /// + public AxisControl latitude { get; protected set; } + + /// + /// Longitude in degrees. + /// + public AxisControl longitude { get; protected set; } + + /// + /// Altitude in meters. + /// + public AxisControl altitude { get; protected set; } + + /// + /// Horizontal accuracy of the reading in meters. + /// + public AxisControl horizontalAccuracy { get; protected set; } + + /// + /// Vertical accuracy of the reading in meters. + /// + public AxisControl verticalAccuracy { get; protected set; } + + /// + /// Time the reading was taken, in seconds since the epoch used by the platform location service. + /// + public DoubleControl timestamp { get; protected set; } + + /// + /// The location sensor that was last added or had activity last. + /// + /// Current location sensor or null. + public static LocationSensor current { get; private set; } + + /// + public override void MakeCurrent() + { + base.MakeCurrent(); + current = this; + } + + /// + protected override void OnRemoved() + { + base.OnRemoved(); + if (current == this) + current = null; + } + + /// + protected override void FinishSetup() + { + latitude = GetChildControl("latitude"); + longitude = GetChildControl("longitude"); + altitude = GetChildControl("altitude"); + horizontalAccuracy = GetChildControl("horizontalAccuracy"); + verticalAccuracy = GetChildControl("verticalAccuracy"); + timestamp = GetChildControl("timestamp"); + base.FinishSetup(); + } + + /// + /// Current status of the location service. + /// + /// + /// After the sensor is enabled the service starts asynchronously, passing through + /// before it reaches + /// . Readings are only valid while running. + /// + public LocationServiceStatus status + { + get + { + var command = QueryLocationStatusCommand.Create(); + if (ExecuteCommand(ref command) >= 0) + return (LocationServiceStatus)command.status; + return LocationServiceStatus.Stopped; // no native impl (editor/desktop) -> degrades + } + } + + /// + /// Whether the user has granted the app permission to access the device location. + /// + /// + /// A user can grant permission while the service is not running. If permission is denied, + /// the service won't reach . + /// + public bool isEnabledByUser + { + get + { + var command = QueryLocationEnabledByUserCommand.Create(); + if (ExecuteCommand(ref command) >= 0) + return command.enabledByUser; + return false; + } + } + + /// + /// Sets the desired accuracy and update-distance threshold for location readings. + /// + /// Desired horizontal accuracy, in meters. + /// Minimum distance the device must move before a new reading is reported, in meters. + /// + /// By default, the sensor is configured with the values from + /// and . return to those defaults. + /// + /// If the sensor is already enabled, readings may briefly pause while they are applied. + /// If the sensor is disabled, values apply when device is enabled. + /// + public void Configure(float desiredAccuracyInMeters, float updateDistanceInMeters) + { + var command = ConfigureLocationCommand.Create(desiredAccuracyInMeters, updateDistanceInMeters); + ExecuteCommand(ref command); + } + + /// + /// Reverts the accuracy and update-distance threshold to the defaults. + /// + /// + /// Subject to the same application timing as . + /// + public void ResetConfiguration() + { + var settings = InputSystem.settings; + Configure(settings.locationAccuracy, settings.locationDistanceThreshold); + } + + /// + protected override void OnAdded() + { + base.OnAdded(); + + // Seed InputSettings defaults into native once on add. + ResetConfiguration(); + } + } } diff --git a/Packages/com.unity.inputsystem/InputSystem/Runtime/InputManager.cs b/Packages/com.unity.inputsystem/InputSystem/Runtime/InputManager.cs index 994538ecc2..ac1045e027 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Runtime/InputManager.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Runtime/InputManager.cs @@ -2073,6 +2073,7 @@ internal void InitializeData() RegisterControlLayout("HumiditySensor", typeof(HumiditySensor)); RegisterControlLayout("AmbientTemperatureSensor", typeof(AmbientTemperatureSensor)); RegisterControlLayout("StepCounter", typeof(StepCounter)); + RegisterControlLayout("LocationSensor", typeof(LocationSensor)); RegisterControlLayout("TrackedDevice", typeof(TrackedDevice)); // Precompiled layouts. diff --git a/Packages/com.unity.inputsystem/InputSystem/Runtime/InputSettings.cs b/Packages/com.unity.inputsystem/InputSystem/Runtime/InputSettings.cs index 74220921c4..21e6e9dd7a 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Runtime/InputSettings.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Runtime/InputSettings.cs @@ -466,6 +466,48 @@ public float multiTapDelayTime } } + /// + /// The desired accuracy of location updates reported by , in meters. + /// + /// Desired horizontal accuracy in meters. Default is 10 meters. + /// + /// Note that the accuracy achieved is hardware and platform-dependent. A finer accuracy can increase power use. + /// + /// + public float locationAccuracy + { + get => m_LocationAccuracy; + set + { + // ReSharper disable once CompareOfFloatsByEqualityOperator + if (m_LocationAccuracy == value) + return; + m_LocationAccuracy = Mathf.Max(0f, value); + OnChange(); + } + } + + /// + /// The minimum distance, in meters, the device must move before reports an update. + /// + /// Minimum update distance in meters. Default is 10 meters. + /// + /// A larger threshold reports updates less often as the device moves, which can lower power use. + /// + /// + public float locationDistanceThreshold + { + get => m_LocationDistanceThreshold; + set + { + // ReSharper disable once CompareOfFloatsByEqualityOperator + if (m_LocationDistanceThreshold == value) + return; + m_LocationDistanceThreshold = Mathf.Max(0f, value); + OnChange(); + } + } + /// /// When Application.runInBackground is true, this property determines what happens when application focus changes /// (see Application.isFocused) changes and how we handle @@ -793,6 +835,8 @@ public void SetInternalFeatureFlag(string featureName, bool enabled) [SerializeField] private float m_DefaultHoldTime = 0.4f; [SerializeField] private float m_TapRadius = 5; [SerializeField] private float m_MultiTapDelayTime = 0.75f; + [SerializeField] private float m_LocationAccuracy = 10f; + [SerializeField] private float m_LocationDistanceThreshold = 10f; [SerializeField] private bool m_DisableRedundantEventsMerging = false; [SerializeField] private bool m_ShortcutKeysConsumeInputs = false; // This is the shortcut support from v1.4. Temporarily moved here as an opt-in feature, while it's issues are investigated. [SerializeField] private bool m_ShortcutKeysUseActionPriority = false; @@ -1087,6 +1131,8 @@ internal static bool AreEqual(InputSettings a, InputSettings b) CompareFloats(a.defaultHoldTime, b.defaultHoldTime) && CompareFloats(a.tapRadius, b.tapRadius) && CompareFloats(a.multiTapDelayTime, b.multiTapDelayTime) && + CompareFloats(a.locationAccuracy, b.locationAccuracy) && + CompareFloats(a.locationDistanceThreshold, b.locationDistanceThreshold) && a.backgroundBehavior == b.backgroundBehavior && a.editorInputBehaviorInPlayMode == b.editorInputBehaviorInPlayMode && a.inputActionPropertyDrawerMode == b.inputActionPropertyDrawerMode &&