A game about forced loneliness, made by TACStudios
1using System; 2using UnityEngine.InputSystem.Controls; 3using UnityEngine.InputSystem.Layouts; 4using UnityEngine.InputSystem.LowLevel; 5using UnityEngine.InputSystem.Utilities; 6 7////TODO: make the sensors return values through their device 8//// (e.g. GravitySensor should itself be an InputControl returning a Vector3 value which is the gravity value) 9 10////REVIEW: Is there a better way than having all the sensor classes? 11 12namespace UnityEngine.InputSystem.LowLevel 13{ 14 internal struct AccelerometerState : IInputStateTypeInfo 15 { 16 public static FourCC kFormat => new FourCC('A', 'C', 'C', 'L'); 17 18 [InputControl(displayName = "Acceleration", processors = "CompensateDirection", noisy = true)] 19 public Vector3 acceleration; 20 21 public FourCC format => kFormat; 22 } 23 24 internal struct GyroscopeState : IInputStateTypeInfo 25 { 26 public static FourCC kFormat => new FourCC('G', 'Y', 'R', 'O'); 27 28 [InputControl(displayName = "Angular Velocity", processors = "CompensateDirection", noisy = true)] 29 public Vector3 angularVelocity; 30 31 public FourCC format => kFormat; 32 } 33 34 internal struct GravityState : IInputStateTypeInfo 35 { 36 public static FourCC kFormat => new FourCC('G', 'R', 'V', ' '); 37 38 [InputControl(displayName = "Gravity", processors = "CompensateDirection", noisy = true)] 39 public Vector3 gravity; 40 41 public FourCC format => kFormat; 42 } 43 44 internal struct AttitudeState : IInputStateTypeInfo 45 { 46 public static FourCC kFormat => new FourCC('A', 'T', 'T', 'D'); 47 48 [InputControl(displayName = "Attitude", processors = "CompensateRotation", noisy = true)] 49 public Quaternion attitude; 50 51 public FourCC format => kFormat; 52 } 53 54 internal struct LinearAccelerationState : IInputStateTypeInfo 55 { 56 public static FourCC kFormat => new FourCC('L', 'A', 'A', 'C'); 57 58 [InputControl(displayName = "Acceleration", processors = "CompensateDirection", noisy = true)] 59 public Vector3 acceleration; 60 61 public FourCC format => kFormat; 62 } 63} 64 65namespace UnityEngine.InputSystem 66{ 67 /// <summary> 68 /// Base class representing any sensor kind of input device. 69 /// </summary> 70 /// <remarks> 71 /// Sensors represent device environmental sensors, such as <see cref="Accelerometer"/>s, <see cref="Gyroscope"/>s, 72 /// <see cref="GravitySensor"/>s and others. 73 /// 74 /// Unlike other devices, sensor devices usually start out in a disabled state in order to reduce energy 75 /// consumption (i.e. preserve battery life) when the sensors are not in fact used. To enable a specific sensor, 76 /// call <see cref="InputSystem.EnableDevice"/> on the device instance. 77 /// 78 /// <example> 79 /// <code> 80 /// // Enable the gyroscope. 81 /// InputSystem.EnableDevice(Gyroscope.current); 82 /// </code> 83 /// </example> 84 /// 85 /// Sensors are usually sampled automatically by the platform at regular intervals. For example, if a sensor 86 /// is sampled at 50Hz, the platform will queue an event with an update at a rate of roughly 50 events per 87 /// second. The default sampling rate for a sensor is usually platform-specific. A custom sampling frequency 88 /// can be set through <see cref="samplingFrequency"/> but be aware that there may be limitations for how fast 89 /// a given sensor can be sampled. 90 /// </remarks> 91 [InputControlLayout(isGenericTypeOfDevice = true)] 92 public class Sensor : InputDevice 93 { 94 /// <summary> 95 /// The frequency (in Hertz) at which the underlying sensor will be refreshed and at which update 96 /// events for it will be queued. 97 /// </summary> 98 /// <value>Times per second at which the sensor is refreshed.</value> 99 /// <remarks> 100 /// Note that when setting sampling frequencies, there may be limits on the range of frequencies 101 /// supported by the underlying hardware/platform. 102 /// 103 /// To support querying sampling frequencies, a sensor device must implement <see cref="QuerySamplingFrequencyCommand"/>. 104 /// To support setting frequencies, it must implemenet <see cref="SetSamplingFrequencyCommand"/>. 105 /// </remarks> 106 /// <exception cref="NotSupportedException">Thrown when reading the property and the underlying 107 /// sensor does not support querying of sampling frequencies.</exception> 108 public float samplingFrequency 109 { 110 get 111 { 112 var command = QuerySamplingFrequencyCommand.Create(); 113 if (ExecuteCommand(ref command) >= 0) 114 return command.frequency; 115 throw new NotSupportedException($"Device '{this}' does not support querying sampling frequency"); 116 } 117 set 118 { 119 ////REVIEW: should this throw NotSupportedException, too? 120 var command = SetSamplingFrequencyCommand.Create(value); 121 ExecuteCommand(ref command); 122 } 123 } 124 } 125 126 /// <summary> 127 /// Input device representing an accelerometer sensor. 128 /// </summary> 129 /// <remarks> 130 /// An accelerometer let's you measure the acceleration of a device, and can be useful to control content by moving a device around. 131 /// Note that the accelerometer will report the acceleration measured on a device both due to moving the device around, and due gravity 132 /// pulling the device down. You can use <see cref="GravitySensor"/> and <see cref="LinearAccelerationSensor"/> to get decoupled values 133 /// for these. 134 /// 135 /// <example> 136 /// <code> 137 /// class MyBehavior : MonoBehaviour 138 /// { 139 /// protected void OnEnable() 140 /// { 141 /// // All sensors start out disabled so they have to manually be enabled first. 142 /// InputSystem.EnableDevice(Accelerometer.current); 143 /// } 144 /// 145 /// protected void OnDisable() 146 /// { 147 /// InputSystem.DisableDevice(Accelerometer.current); 148 /// } 149 /// 150 /// protected void Update() 151 /// { 152 /// var acceleration = Accelerometer.current.acceleration.ReadValue(); 153 /// //... 154 /// } 155 /// } 156 /// </code> 157 /// </example> 158 /// </remarks> 159 [InputControlLayout(stateType = typeof(AccelerometerState))] 160 public class Accelerometer : Sensor 161 { 162 public Vector3Control acceleration { get; protected set; } 163 164 /// <summary> 165 /// The accelerometer that was last added or had activity last. 166 /// </summary> 167 /// <value>Current accelerometer or <c>null</c>.</value> 168 public static Accelerometer current { get; private set; } 169 170 /// <inheritdoc /> 171 public override void MakeCurrent() 172 { 173 base.MakeCurrent(); 174 current = this; 175 } 176 177 /// <inheritdoc /> 178 protected override void OnRemoved() 179 { 180 base.OnRemoved(); 181 if (current == this) 182 current = null; 183 } 184 185 /// <inheritdoc /> 186 protected override void FinishSetup() 187 { 188 acceleration = GetChildControl<Vector3Control>("acceleration"); 189 base.FinishSetup(); 190 } 191 } 192 193 /// <summary> 194 /// Input device representing a gyroscope sensor. 195 /// </summary> 196 /// <remarks> 197 /// A gyroscope lets you measure the angular velocity of a device, and can be useful to control content by rotating a device. 198 /// </remarks> 199 [InputControlLayout(stateType = typeof(GyroscopeState))] 200 public class Gyroscope : Sensor 201 { 202 public Vector3Control angularVelocity { get; protected set; } 203 204 /// <summary> 205 /// The gyroscope that was last added or had activity last. 206 /// </summary> 207 /// <value>Current gyroscope or <c>null</c>.</value> 208 public static Gyroscope current { get; private set; } 209 210 /// <inheritdoc /> 211 public override void MakeCurrent() 212 { 213 base.MakeCurrent(); 214 current = this; 215 } 216 217 /// <inheritdoc /> 218 protected override void OnRemoved() 219 { 220 base.OnRemoved(); 221 if (current == this) 222 current = null; 223 } 224 225 /// <inheritdoc /> 226 protected override void FinishSetup() 227 { 228 angularVelocity = GetChildControl<Vector3Control>("angularVelocity"); 229 base.FinishSetup(); 230 } 231 } 232 233 /// <summary> 234 /// Input device representing a gravity sensor. 235 /// </summary> 236 /// <remarks> 237 /// 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. 238 /// This is usually derived from a hardware <see cref="Accelerometer"/>, by subtracting the effect of linear acceleration (see <see cref="LinearAccelerationSensor"/>). 239 /// </remarks> 240 [InputControlLayout(stateType = typeof(GravityState), displayName = "Gravity")] 241 public class GravitySensor : Sensor 242 { 243 public Vector3Control gravity { get; protected set; } 244 245 /// <summary> 246 /// The gravity sensor that was last added or had activity last. 247 /// </summary> 248 /// <value>Current gravity sensor or <c>null</c>.</value> 249 public static GravitySensor current { get; private set; } 250 251 /// <inheritdoc /> 252 protected override void FinishSetup() 253 { 254 gravity = GetChildControl<Vector3Control>("gravity"); 255 base.FinishSetup(); 256 } 257 258 /// <inheritdoc /> 259 public override void MakeCurrent() 260 { 261 base.MakeCurrent(); 262 current = this; 263 } 264 265 /// <inheritdoc /> 266 protected override void OnRemoved() 267 { 268 base.OnRemoved(); 269 if (current == this) 270 current = null; 271 } 272 } 273 274 //// 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." 275 //// This is the same as https://docs.unity3d.com/ScriptReference/Gyroscope-attitude.html 276 /// <summary> 277 /// Input device representing an attitude sensor. 278 /// </summary> 279 /// <remarks> 280 /// An attitude sensor let's you determine the orientation of a device, and can be useful to control content by rotating a device. 281 /// </remarks> 282 [InputControlLayout(stateType = typeof(AttitudeState), displayName = "Attitude")] 283 public class AttitudeSensor : Sensor 284 { 285 public QuaternionControl attitude { get; protected set; } 286 287 /// <summary> 288 /// The attitude sensor that was last added or had activity last. 289 /// </summary> 290 /// <value>Current attitude sensor or <c>null</c>.</value> 291 public static AttitudeSensor current { get; private set; } 292 293 /// <inheritdoc /> 294 public override void MakeCurrent() 295 { 296 base.MakeCurrent(); 297 current = this; 298 } 299 300 /// <inheritdoc /> 301 protected override void OnRemoved() 302 { 303 base.OnRemoved(); 304 if (current == this) 305 current = null; 306 } 307 308 /// <inheritdoc /> 309 protected override void FinishSetup() 310 { 311 attitude = GetChildControl<QuaternionControl>("attitude"); 312 base.FinishSetup(); 313 } 314 } 315 316 /// <summary> 317 /// Input device representing linear acceleration affecting the device playing the content. 318 /// </summary> 319 /// <remarks> 320 /// An accelerometer let's you measure the acceleration of a device, and can be useful to control content by moving a device around. 321 /// Linear acceleration is the acceleration of a device unaffected by gravity forces. 322 /// This is usually derived from a hardware <see cref="Accelerometer"/>, by subtracting the effect of gravity (see <see cref="GravitySensor"/>). 323 /// </remarks> 324 [InputControlLayout(stateType = typeof(LinearAccelerationState), displayName = "Linear Acceleration")] 325 public class LinearAccelerationSensor : Sensor 326 { 327 public Vector3Control acceleration { get; protected set; } 328 329 /// <summary> 330 /// The linear acceleration sensor that was last added or had activity last. 331 /// </summary> 332 /// <value>Current linear acceleration sensor or <c>null</c>.</value> 333 public static LinearAccelerationSensor current { get; private set; } 334 335 /// <inheritdoc /> 336 public override void MakeCurrent() 337 { 338 base.MakeCurrent(); 339 current = this; 340 } 341 342 /// <inheritdoc /> 343 protected override void OnRemoved() 344 { 345 base.OnRemoved(); 346 if (current == this) 347 current = null; 348 } 349 350 /// <inheritdoc /> 351 protected override void FinishSetup() 352 { 353 acceleration = GetChildControl<Vector3Control>("acceleration"); 354 base.FinishSetup(); 355 } 356 } 357 358 /// <summary> 359 /// Input device representing the magnetic field affecting the device playing the content. 360 /// </summary> 361 [InputControlLayout(displayName = "Magnetic Field")] 362 public class MagneticFieldSensor : Sensor 363 { 364 /// <summary> 365 /// Strength of the magnetic field reported by the sensor. 366 /// </summary> 367 /// <value>Control representing the strength of the magnetic field.</value> 368 /// <remarks> 369 /// Values are in micro-Tesla (uT) and measure the ambient magnetic field in the X, Y and Z axis. 370 /// </remarks> 371 [InputControl(displayName = "Magnetic Field", noisy = true)] 372 public Vector3Control magneticField { get; protected set; } 373 374 /// <summary> 375 /// The linear acceleration sensor that was last added or had activity last. 376 /// </summary> 377 /// <value>Current linear acceleration sensor or <c>null</c>.</value> 378 public static MagneticFieldSensor current { get; private set; } 379 380 /// <inheritdoc /> 381 public override void MakeCurrent() 382 { 383 base.MakeCurrent(); 384 current = this; 385 } 386 387 /// <inheritdoc /> 388 protected override void OnRemoved() 389 { 390 base.OnRemoved(); 391 if (current == this) 392 current = null; 393 } 394 395 /// <inheritdoc /> 396 protected override void FinishSetup() 397 { 398 magneticField = GetChildControl<Vector3Control>("magneticField"); 399 base.FinishSetup(); 400 } 401 } 402 403 /// <summary> 404 /// Input device representing the ambient light measured by the device playing the content. 405 /// </summary> 406 [InputControlLayout(displayName = "Light")] 407 public class LightSensor : Sensor 408 { 409 /// <summary> 410 /// Light level in SI lux units. 411 /// </summary> 412 [InputControl(displayName = "Light Level", noisy = true)] 413 public AxisControl lightLevel { get; protected set; } 414 415 /// <summary> 416 /// The light sensor that was last added or had activity last. 417 /// </summary> 418 /// <value>Current light sensor or <c>null</c>.</value> 419 public static LightSensor current { get; private set; } 420 421 /// <inheritdoc /> 422 public override void MakeCurrent() 423 { 424 base.MakeCurrent(); 425 current = this; 426 } 427 428 /// <inheritdoc /> 429 protected override void OnRemoved() 430 { 431 base.OnRemoved(); 432 if (current == this) 433 current = null; 434 } 435 436 /// <inheritdoc /> 437 protected override void FinishSetup() 438 { 439 lightLevel = GetChildControl<AxisControl>("lightLevel"); 440 base.FinishSetup(); 441 } 442 } 443 444 /// <summary> 445 /// Input device representing the atmospheric pressure measured by the device playing the content. 446 /// </summary> 447 [InputControlLayout(displayName = "Pressure")] 448 public class PressureSensor : Sensor 449 { 450 /// <summary> 451 /// Atmospheric pressure in hPa (millibar). 452 /// </summary> 453 [InputControl(displayName = "Atmospheric Pressure", noisy = true)] 454 public AxisControl atmosphericPressure { get; protected set; } 455 456 /// <summary> 457 /// The pressure sensor that was last added or had activity last. 458 /// </summary> 459 /// <value>Current pressure sensor or <c>null</c>.</value> 460 public static PressureSensor current { get; private set; } 461 462 /// <inheritdoc /> 463 public override void MakeCurrent() 464 { 465 base.MakeCurrent(); 466 current = this; 467 } 468 469 /// <inheritdoc /> 470 protected override void OnRemoved() 471 { 472 base.OnRemoved(); 473 if (current == this) 474 current = null; 475 } 476 477 /// <inheritdoc /> 478 protected override void FinishSetup() 479 { 480 atmosphericPressure = GetChildControl<AxisControl>("atmosphericPressure"); 481 base.FinishSetup(); 482 } 483 } 484 485 /// <summary> 486 /// Input device representing the proximity of the device playing the content to the user. 487 /// </summary> 488 /// <remarks> 489 /// The proximity sensor is usually used by phones to determine if the user is holding the phone to their ear or not. 490 /// </remarks> 491 [InputControlLayout(displayName = "Proximity")] 492 public class ProximitySensor : Sensor 493 { 494 /// <summary> 495 /// Proximity sensor distance measured in centimeters. 496 /// </summary> 497 [InputControl(displayName = "Distance", noisy = true)] 498 public AxisControl distance { get; protected set; } 499 500 /// <summary> 501 /// The proximity sensor that was last added or had activity last. 502 /// </summary> 503 /// <value>Current proximity sensor or <c>null</c>.</value> 504 public static ProximitySensor current { get; private set; } 505 506 /// <inheritdoc /> 507 public override void MakeCurrent() 508 { 509 base.MakeCurrent(); 510 current = this; 511 } 512 513 /// <inheritdoc /> 514 protected override void OnRemoved() 515 { 516 base.OnRemoved(); 517 if (current == this) 518 current = null; 519 } 520 521 /// <inheritdoc /> 522 protected override void FinishSetup() 523 { 524 distance = GetChildControl<AxisControl>("distance"); 525 base.FinishSetup(); 526 } 527 } 528 529 /// <summary> 530 /// Input device representing the ambient air humidity measured by the device playing the content. 531 /// </summary> 532 [InputControlLayout(displayName = "Humidity")] 533 public class HumiditySensor : Sensor 534 { 535 /// <summary> 536 /// Relative ambient air humidity in percent. 537 /// </summary> 538 [InputControl(displayName = "Relative Humidity", noisy = true)] 539 public AxisControl relativeHumidity { get; protected set; } 540 541 /// <summary> 542 /// The humidity sensor that was last added or had activity last. 543 /// </summary> 544 /// <value>Current humidity sensor or <c>null</c>.</value> 545 public static HumiditySensor current { get; private set; } 546 547 /// <inheritdoc /> 548 public override void MakeCurrent() 549 { 550 base.MakeCurrent(); 551 current = this; 552 } 553 554 /// <inheritdoc /> 555 protected override void OnRemoved() 556 { 557 base.OnRemoved(); 558 if (current == this) 559 current = null; 560 } 561 562 /// <inheritdoc /> 563 protected override void FinishSetup() 564 { 565 relativeHumidity = GetChildControl<AxisControl>("relativeHumidity"); 566 base.FinishSetup(); 567 } 568 } 569 570 /// <summary> 571 /// Input device representing the ambient air temperature measured by the device playing the content. 572 /// </summary> 573 [InputControlLayout(displayName = "Ambient Temperature")] 574 public class AmbientTemperatureSensor : Sensor 575 { 576 /// <summary> 577 /// Temperature in degree Celsius. 578 /// </summary> 579 [InputControl(displayName = "Ambient Temperature", noisy = true)] 580 public AxisControl ambientTemperature { get; protected set; } 581 582 /// <summary> 583 /// The ambient temperature sensor that was last added or had activity last. 584 /// </summary> 585 /// <value>Current ambient temperature sensor or <c>null</c>.</value> 586 public static AmbientTemperatureSensor current { get; private set; } 587 588 /// <inheritdoc /> 589 public override void MakeCurrent() 590 { 591 base.MakeCurrent(); 592 current = this; 593 } 594 595 /// <inheritdoc /> 596 protected override void OnRemoved() 597 { 598 base.OnRemoved(); 599 if (current == this) 600 current = null; 601 } 602 603 /// <inheritdoc /> 604 protected override void FinishSetup() 605 { 606 ambientTemperature = GetChildControl<AxisControl>("ambientTemperature"); 607 base.FinishSetup(); 608 } 609 } 610 611 /// <summary> 612 /// Input device representing the foot steps taken by the user as measured by the device playing the content. 613 /// </summary> 614 /// <remarks> 615 /// On iOS, access to the step counter must be enabled via <see cref="InputSettings.iOSSettings.motionUsage"/>. 616 /// </remarks> 617 [InputControlLayout(displayName = "Step Counter")] 618 public class StepCounter : Sensor 619 { 620 /// <summary> 621 /// The number of steps taken by the user since the last reboot while activated. 622 /// </summary> 623 [InputControl(displayName = "Step Counter", noisy = true)] 624 public IntegerControl stepCounter { get; protected set; } 625 626 /// <summary> 627 /// The step counter that was last added or had activity last. 628 /// </summary> 629 /// <value>Current step counter or <c>null</c>.</value> 630 public static StepCounter current { get; private set; } 631 632 /// <inheritdoc /> 633 public override void MakeCurrent() 634 { 635 base.MakeCurrent(); 636 current = this; 637 } 638 639 /// <inheritdoc /> 640 protected override void OnRemoved() 641 { 642 base.OnRemoved(); 643 if (current == this) 644 current = null; 645 } 646 647 /// <inheritdoc /> 648 protected override void FinishSetup() 649 { 650 stepCounter = GetChildControl<IntegerControl>("stepCounter"); 651 base.FinishSetup(); 652 } 653 } 654 655 /// <summary> 656 /// Hinge angle sensor. 657 /// This sensor is usually available on foldable devices. 658 /// Note: The step resolution for angle is device dependentent, on Android you can query the sensor resolution by querying device capabilities. 659 /// </summary> 660 [InputControlLayout(displayName = "Hinge Angle")] 661 public class HingeAngle : Sensor 662 { 663 /// <summary> 664 /// The angle in degrees on how much the device is unfolded. 665 /// </summary> 666 /// <value>0 means fully folded, 180 means fully unfolded.</value> 667 public AxisControl angle { get; protected set; } 668 669 /// <summary> 670 /// The hinge angle sensor that was last added or had activity last. 671 /// </summary> 672 /// <value>Current hinge angle sensor or <c>null</c>.</value> 673 public static HingeAngle current { get; private set; } 674 675 /// <inheritdoc /> 676 public override void MakeCurrent() 677 { 678 base.MakeCurrent(); 679 current = this; 680 } 681 682 /// <inheritdoc /> 683 protected override void OnRemoved() 684 { 685 base.OnRemoved(); 686 if (current == this) 687 current = null; 688 } 689 690 /// <inheritdoc /> 691 protected override void FinishSetup() 692 { 693 angle = GetChildControl<AxisControl>("angle"); 694 base.FinishSetup(); 695 } 696 } 697}