using System; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Layouts; using UnityEngine.InputSystem.LowLevel; using UnityEngine.InputSystem.Utilities; ////TODO: make the sensors return values through their device //// (e.g. GravitySensor should itself be an InputControl returning a Vector3 value which is the gravity value) ////REVIEW: Is there a better way than having all the sensor classes? namespace UnityEngine.InputSystem.LowLevel { internal struct AccelerometerState : IInputStateTypeInfo { public static FourCC kFormat => new FourCC('A', 'C', 'C', 'L'); [InputControl(displayName = "Acceleration", processors = "CompensateDirection", noisy = true)] public Vector3 acceleration; public FourCC format => kFormat; } internal struct GyroscopeState : IInputStateTypeInfo { public static FourCC kFormat => new FourCC('G', 'Y', 'R', 'O'); [InputControl(displayName = "Angular Velocity", processors = "CompensateDirection", noisy = true)] public Vector3 angularVelocity; public FourCC format => kFormat; } internal struct GravityState : IInputStateTypeInfo { public static FourCC kFormat => new FourCC('G', 'R', 'V', ' '); [InputControl(displayName = "Gravity", processors = "CompensateDirection", noisy = true)] public Vector3 gravity; public FourCC format => kFormat; } internal struct AttitudeState : IInputStateTypeInfo { public static FourCC kFormat => new FourCC('A', 'T', 'T', 'D'); [InputControl(displayName = "Attitude", processors = "CompensateRotation", noisy = true)] public Quaternion attitude; public FourCC format => kFormat; } internal struct LinearAccelerationState : IInputStateTypeInfo { public static FourCC kFormat => new FourCC('L', 'A', 'A', 'C'); [InputControl(displayName = "Acceleration", processors = "CompensateDirection", noisy = true)] public Vector3 acceleration; public FourCC format => kFormat; } } namespace UnityEngine.InputSystem { /// /// Base class representing any sensor kind of input device. /// /// /// Sensors represent device environmental sensors, such as s, s, /// s and others. /// /// Unlike other devices, sensor devices usually start out in a disabled state in order to reduce energy /// consumption (i.e. preserve battery life) when the sensors are not in fact used. To enable a specific sensor, /// call on the device instance. /// /// /// /// // Enable the gyroscope. /// InputSystem.EnableDevice(Gyroscope.current); /// /// /// /// Sensors are usually sampled automatically by the platform at regular intervals. For example, if a sensor /// is sampled at 50Hz, the platform will queue an event with an update at a rate of roughly 50 events per /// second. The default sampling rate for a sensor is usually platform-specific. A custom sampling frequency /// can be set through but be aware that there may be limitations for how fast /// a given sensor can be sampled. /// [InputControlLayout(isGenericTypeOfDevice = true)] public class Sensor : InputDevice { /// /// The frequency (in Hertz) at which the underlying sensor will be refreshed and at which update /// events for it will be queued. /// /// Times per second at which the sensor is refreshed. /// /// Note that when setting sampling frequencies, there may be limits on the range of frequencies /// supported by the underlying hardware/platform. /// /// To support querying sampling frequencies, a sensor device must implement . /// To support setting frequencies, it must implemenet . /// /// Thrown when reading the property and the underlying /// sensor does not support querying of sampling frequencies. public float samplingFrequency { get { var command = QuerySamplingFrequencyCommand.Create(); if (ExecuteCommand(ref command) >= 0) return command.frequency; throw new NotSupportedException($"Device '{this}' does not support querying sampling frequency"); } set { ////REVIEW: should this throw NotSupportedException, too? var command = SetSamplingFrequencyCommand.Create(value); ExecuteCommand(ref command); } } } /// /// Input device representing an accelerometer sensor. /// /// /// An accelerometer let's you measure the acceleration of a device, and can be useful to control content by moving a device around. /// Note that the accelerometer will report the acceleration measured on a device both due to moving the device around, and due gravity /// pulling the device down. You can use and to get decoupled values /// for these. /// /// /// /// class MyBehavior : MonoBehaviour /// { /// protected void OnEnable() /// { /// // All sensors start out disabled so they have to manually be enabled first. /// InputSystem.EnableDevice(Accelerometer.current); /// } /// /// protected void OnDisable() /// { /// InputSystem.DisableDevice(Accelerometer.current); /// } /// /// protected void Update() /// { /// var acceleration = Accelerometer.current.acceleration.ReadValue(); /// //... /// } /// } /// /// /// [InputControlLayout(stateType = typeof(AccelerometerState))] public class Accelerometer : Sensor { public Vector3Control acceleration { get; private set; } /// /// The accelerometer that was last added or had activity last. /// /// Current accelerometer or null. public static Accelerometer 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() { acceleration = GetChildControl("acceleration"); base.FinishSetup(); } } /// /// Input device representing a gyroscope sensor. /// /// /// A gyroscope let's you measure the angular velocity of a device, and can be useful to control content by rotating a device. /// [InputControlLayout(stateType = typeof(GyroscopeState))] public class Gyroscope : Sensor { public Vector3Control angularVelocity { get; private set; } /// /// The gyroscope that was last added or had activity last. /// /// Current gyroscope or null. public static Gyroscope 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() { angularVelocity = GetChildControl("angularVelocity"); base.FinishSetup(); } } /// /// Input device representing a gravity sensor. /// /// /// A gravity sensor let's you determine the direction of the gravity vector relative to a device, and can be useful to control content by device orientation. /// This is usually derived from a hardware , by subtracting the effect of linear acceleration (see ). /// [InputControlLayout(stateType = typeof(GravityState), displayName = "Gravity")] public class GravitySensor : Sensor { public Vector3Control gravity { get; private set; } /// /// The gravity sensor that was last added or had activity last. /// /// Current gravity sensor or null. public static GravitySensor current { get; private set; } /// protected override void FinishSetup() { gravity = GetChildControl("gravity"); base.FinishSetup(); } /// public override void MakeCurrent() { base.MakeCurrent(); current = this; } /// protected override void OnRemoved() { base.OnRemoved(); if (current == this) current = null; } } //// REVIEW: Is this name good enough, possible other name RotationVector, here's how Android docs describe it. "A rotation vector sensor reports the orientation of the device relative to the East-North-Up coordinates frame." //// This is the same as https://docs.unity3d.com/ScriptReference/Gyroscope-attitude.html /// /// Input device representing an attitude sensor. /// /// /// An attitude sensor let's you determine the orientation of a device, and can be useful to control content by rotating a device. /// [InputControlLayout(stateType = typeof(AttitudeState), displayName = "Attitude")] public class AttitudeSensor : Sensor { public QuaternionControl attitude { get; private set; } /// /// The attitude sensor that was last added or had activity last. /// /// Current attitude sensor or null. public static AttitudeSensor 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() { attitude = GetChildControl("attitude"); base.FinishSetup(); } } /// /// Input device representing linear acceleration affecting the device playing the content. /// /// /// An accelerometer let's you measure the acceleration of a device, and can be useful to control content by moving a device around. /// Linear acceleration is the acceleration of a device unaffected by gravity forces. /// This is usually derived from a hardware , by subtracting the effect of gravity (see ). /// [InputControlLayout(stateType = typeof(LinearAccelerationState), displayName = "Linear Acceleration")] public class LinearAccelerationSensor : Sensor { public Vector3Control acceleration { get; private set; } /// /// The linear acceleration sensor that was last added or had activity last. /// /// Current linear acceleration sensor or null. public static LinearAccelerationSensor 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() { acceleration = GetChildControl("acceleration"); base.FinishSetup(); } } /// /// Input device representing the magnetic field affecting the device playing the content. /// [InputControlLayout(displayName = "Magnetic Field")] public class MagneticFieldSensor : Sensor { /// /// Strength of the magnetic field reported by the sensor. /// /// Control representing the strength of the magnetic field. /// /// Values are in micro-Tesla (uT) and measure the ambient magnetic field in the X, Y and Z axis. /// [InputControl(displayName = "Magnetic Field", noisy = true)] public Vector3Control magneticField { get; private set; } /// /// The linear acceleration sensor that was last added or had activity last. /// /// Current linear acceleration sensor or null. public static MagneticFieldSensor 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() { magneticField = GetChildControl("magneticField"); base.FinishSetup(); } } /// /// Input device representing the ambient light measured by the device playing the content. /// [InputControlLayout(displayName = "Light")] public class LightSensor : Sensor { /// /// Light level in SI lux units. /// [InputControl(displayName = "Light Level", noisy = true)] public AxisControl lightLevel { get; private set; } /// /// The light sensor that was last added or had activity last. /// /// Current light sensor or null. public static LightSensor 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() { lightLevel = GetChildControl("lightLevel"); base.FinishSetup(); } } /// /// Input device representing the atmospheric pressure measured by the device playing the content. /// [InputControlLayout(displayName = "Pressure")] public class PressureSensor : Sensor { /// /// Atmospheric pressure in hPa (millibar). /// [InputControl(displayName = "Atmospheric Pressure", noisy = true)] public AxisControl atmosphericPressure { get; private set; } /// /// The pressure sensor that was last added or had activity last. /// /// Current pressure sensor or null. public static PressureSensor 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() { atmosphericPressure = GetChildControl("atmosphericPressure"); base.FinishSetup(); } } /// /// Input device representing the proximity of the device playing the content to the user. /// /// /// The proximity sensor is usually used by phones to determine if the user is holding the phone to their ear or not. /// [InputControlLayout(displayName = "Proximity")] public class ProximitySensor : Sensor { /// /// Proximity sensor distance measured in centimeters. /// [InputControl(displayName = "Distance", noisy = true)] public AxisControl distance { get; private set; } /// /// The proximity sensor that was last added or had activity last. /// /// Current proximity sensor or null. public static ProximitySensor 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() { distance = GetChildControl("distance"); base.FinishSetup(); } } /// /// Input device representing the ambient air humidity measured by the device playing the content. /// [InputControlLayout(displayName = "Humidity")] public class HumiditySensor : Sensor { /// /// Relative ambient air humidity in percent. /// [InputControl(displayName = "Relative Humidity", noisy = true)] public AxisControl relativeHumidity { get; private set; } /// /// The humidity sensor that was last added or had activity last. /// /// Current humidity sensor or null. public static HumiditySensor 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() { relativeHumidity = GetChildControl("relativeHumidity"); base.FinishSetup(); } } /// /// Input device representing the ambient air temperature measured by the device playing the content. /// [InputControlLayout(displayName = "Ambient Temperature")] public class AmbientTemperatureSensor : Sensor { /// /// Temperature in degree Celsius. /// [InputControl(displayName = "Ambient Temperature", noisy = true)] public AxisControl ambientTemperature { get; private set; } /// /// The ambient temperature sensor that was last added or had activity last. /// /// Current ambient temperature sensor or null. public static AmbientTemperatureSensor 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() { ambientTemperature = GetChildControl("ambientTemperature"); base.FinishSetup(); } } /// /// Input device representing the foot steps taken by the user as measured by the device playing the content. /// /// /// On iOS, access to the step counter must be enabled via . /// [InputControlLayout(displayName = "Step Counter")] public class StepCounter : Sensor { /// /// The number of steps taken by the user since the last reboot while activated. /// [InputControl(displayName = "Step Counter", noisy = true)] public IntegerControl stepCounter { get; private set; } /// /// The step counter that was last added or had activity last. /// /// Current step counter or null. public static StepCounter 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() { stepCounter = GetChildControl("stepCounter"); base.FinishSetup(); } } }