namespace Zinnia.Utility
{
using System.Collections.Generic;
#if UNITY_2019_3_OR_NEWER
using UnityEngine;
#endif
using UnityEngine.XR;
///
/// Wrapper class for properties that have become obsolete in later versions of Unity.
///
public static class XRDeviceProperties
{
///
/// The number of devices found with the same node identifier.
///
/// The node to check for.
/// The number of devices found.
public static int DeviceCount(XRNode node = XRNode.Head)
{
int deviceCount = 0;
#if UNITY_2019_3_OR_NEWER
List devices = new List();
InputDevices.GetDevicesAtXRNode(node, devices);
deviceCount = devices.Count;
#else
List nodeStates = new List();
InputTracking.GetNodeStates(nodeStates);
foreach (XRNodeState nodeState in nodeStates)
{
if (nodeState.nodeType == node)
{
deviceCount++;
}
}
#endif
return deviceCount;
}
///
/// Determines whether the device is present.
///
/// Whether the device is present.
public static bool IsPresent()
{
bool isPresent = false;
#if UNITY_2019_3_OR_NEWER
List xrDisplaySubsystems = new List();
SubsystemManager.GetInstances(xrDisplaySubsystems);
foreach (XRDisplaySubsystem xrDisplay in xrDisplaySubsystems)
{
if (xrDisplay.running)
{
isPresent = true;
}
}
#else
isPresent = XRDevice.isPresent;
#endif
return isPresent;
}
///
/// Determines whether the device has positional tracking.
///
/// The node to check for.
/// Whether the device has positional tracking.
public static bool HasPositionalTracking(XRNode node = XRNode.Head)
{
bool hasPositionalTracking = false;
#if UNITY_2019_3_OR_NEWER
InputDevice positionalTrackingDevice = InputDevices.GetDeviceAtXRNode(node);
if (positionalTrackingDevice != null)
{
positionalTrackingDevice.TryGetFeatureValue(CommonUsages.trackingState, out InputTrackingState trackingState);
hasPositionalTracking = (trackingState & InputTrackingState.Position) != 0;
}
#else
List nodeStates = new List();
InputTracking.GetNodeStates(nodeStates);
foreach (XRNodeState nodeState in nodeStates)
{
if (nodeState.nodeType == node)
{
hasPositionalTracking = nodeState.TryGetPosition(out _);
break;
}
}
#endif
return hasPositionalTracking;
}
///
/// Determines whether the device has rotational tracking.
///
/// The node to check for.
/// Whether the device has rotational tracking.
public static bool HasRotationalTracking(XRNode node = XRNode.Head)
{
bool hasRotationalTracking = false;
#if UNITY_2019_3_OR_NEWER
InputDevice rotationalTrackingDevice = InputDevices.GetDeviceAtXRNode(node);
if (rotationalTrackingDevice != null)
{
rotationalTrackingDevice.TryGetFeatureValue(CommonUsages.trackingState, out InputTrackingState trackingState);
hasRotationalTracking = (trackingState & InputTrackingState.Rotation) != 0;
}
#else
List nodeStates = new List();
InputTracking.GetNodeStates(nodeStates);
foreach (XRNodeState nodeState in nodeStates)
{
if (nodeState.nodeType == node)
{
hasRotationalTracking = nodeState.TryGetRotation(out _);
break;
}
}
#endif
return hasRotationalTracking;
}
///
/// The manufacturer name of the given node.
///
/// The node to check for.
/// The manufacturer name.
public static string Manufacturer(XRNode node = XRNode.Head)
{
string manufacturerName = "";
#if UNITY_2019_3_OR_NEWER
InputDevice manufacturerDevice = InputDevices.GetDeviceAtXRNode(node);
manufacturerName = manufacturerDevice != null && manufacturerDevice.manufacturer != null ? manufacturerDevice.manufacturer : "";
#endif
return manufacturerName;
}
///
/// The model name of the given node.
///
/// The node to check for.
/// The model name.
public static string Model(XRNode node = XRNode.Head)
{
string modelName = "";
#if UNITY_2019_3_OR_NEWER
InputDevice modelDevice = InputDevices.GetDeviceAtXRNode(node);
modelName = modelDevice != null && modelDevice.name != null ? modelDevice.name : "";
#else
modelName = XRDevice.model;
#endif
return modelName;
}
///
/// Determines whether the device is being tracked.
///
/// The node to check for.
/// Whether the device is being tracked.
public static bool IsTracked(XRNode node = XRNode.Head)
{
bool isTracked = false;
#if UNITY_2019_3_OR_NEWER
InputDevice trackedDevice = InputDevices.GetDeviceAtXRNode(node);
if (trackedDevice != null)
{
trackedDevice.TryGetFeatureValue(CommonUsages.isTracked, out isTracked);
}
#else
List nodeStates = new List();
InputTracking.GetNodeStates(nodeStates);
foreach (XRNodeState nodeState in nodeStates)
{
if (nodeState.nodeType == node)
{
isTracked = nodeState.tracked;
break;
}
}
#endif
return isTracked;
}
///
/// Determines whether the device is valid.
///
/// The node to check for.
/// Whether the device is valid.
public static bool IsValid(XRNode node = XRNode.Head)
{
bool isValid = false;
#if UNITY_2019_3_OR_NEWER
InputDevice validDevice = InputDevices.GetDeviceAtXRNode(node);
isValid = validDevice != null && validDevice.isValid;
#endif
return isValid;
}
///
/// The user presence state for the given node.
///
/// The node to check for.
/// The user presence state.
public static string UserPresence(XRNode node = XRNode.Head)
{
string userPresence = "Unknown";
#if UNITY_2019_3_OR_NEWER
InputDevice userPresenceDevice = InputDevices.GetDeviceAtXRNode(node);
if (userPresenceDevice != null)
{
if (userPresenceDevice.TryGetFeatureValue(CommonUsages.userPresence, out bool userPresent))
{
userPresence = userPresent ? "Present" : "NotPresent";
}
else
{
userPresence = "Unsupported";
}
}
#else
userPresence = XRDevice.userPresence.ToString();
#endif
return userPresence;
}
///
/// The current battery level of the device at the given node.
///
/// The node to check for.
/// The current battery level.
public static float BatteryLevel(XRNode node = XRNode.Head)
{
float batteryLevel = -1f;
#if UNITY_2019_3_OR_NEWER
InputDevice batteryLevelDevice = InputDevices.GetDeviceAtXRNode(node);
if (batteryLevelDevice != null)
{
batteryLevelDevice.TryGetFeatureValue(CommonUsages.batteryLevel, out batteryLevel);
}
#endif
return batteryLevel;
}
#if UNITY_2019_3_OR_NEWER
///
/// Returns the first device found at the given node.
///
/// The node to check for.
/// The first found device.
public static InputDevice DeviceInstance(XRNode node = XRNode.Head)
{
List devices = new List();
InputDevices.GetDevicesAtXRNode(node, devices);
if (devices.Count == 0)
{
return default;
}
if (devices.Count > 1)
{
Debug.Log("Multiple devices found at node: " + node);
}
return devices[0];
}
///
/// Determines whether the given device is the same as a default unset device.
///
/// The device to check for.
/// Whether the device is the same as a default unset device.
public static bool IsDeviceDefault(InputDevice device)
{
return device == default;
}
#endif
}
}