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();
}
}
}