using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
namespace Passer.Tracking {
public class UnityXRController : ControllerComponent {
#if pUNITYXR
//public TrackerComponent tracker;
//public Transform sensorTransform {
// get { return this.transform; }
//}
protected InputDevice device;
protected XRNode xrNode;
public GameObject model;
#region Manage
///
/// Find a Unity XR Controller
///
///
///
///
public static UnityXRController Find(UnityXR unityXR, bool isLeft) {
UnityXRController[] controllers = unityXR.GetComponentsInChildren();
foreach (UnityXRController controller in controllers) {
if (controller.isLeft == isLeft)
return controller;
}
return null;
}
///
/// Find or Create a Unity XR Controller
///
///
///
///
public static UnityXRController Get(UnityXR unityXR, bool isLeft, Vector3 position, Quaternion rotation) {
if (unityXR == null || unityXR.transform == null)
return null;
//Transform controllerTransform = tracker.transform.Find(name);
UnityXRController unityController = Find(unityXR, isLeft);
if (unityController == null) {
GameObject trackerObject = new GameObject(isLeft ? "Left Controller" : "Right Controller");
Transform controllerTransform = trackerObject.transform;
controllerTransform.parent = unityXR.transform;
controllerTransform.position = position;
controllerTransform.rotation = rotation;
unityController = controllerTransform.gameObject.AddComponent();
unityController.isLeft = isLeft;
}
return unityController;
}
protected Dictionary modelNames = new Dictionary() {
{ "Oculus Touch Controller - Left", "Left Touch Controller" },
{ "Oculus Touch Controller - Right", "Right Touch Controller" },
};
protected virtual void ShowModel(string deviceName) {
if (model != null)
Destroy(model);
if (deviceName == null)
return;
string modelName = deviceName;
if (modelNames.ContainsKey(modelName))
modelName = modelNames[deviceName];
CreateModel(modelName);
}
protected void CreateModel() {
#if hLEGACY
switch (UnityTracker.DetermineLoadedDevice()) {
case UnityTracker.XRDeviceType.Oculus:
CreateModel(isLeft ? "Left Touch Controller" : "Right Touch Controller");
break;
case UnityTracker.XRDeviceType.OpenVR:
CreateModel("Vive Controller");
break;
case UnityTracker.XRDeviceType.None:
CreateModel("Generic Controller");
break;
}
#endif
}
protected void CreateModel(string resourceName) {
GameObject sensorObject;
if (resourceName == null) {
sensorObject = new GameObject("Model");
}
else {
Object controllerPrefab = Resources.Load(resourceName);
if (controllerPrefab == null)
sensorObject = new GameObject("Model");
else
sensorObject = (GameObject)Instantiate(controllerPrefab);
sensorObject.name = resourceName;
}
model = sensorObject;
model.transform.parent = this.transform;
model.transform.localPosition = Vector3.zero;
model.transform.localRotation = Quaternion.identity;
}
#endregion
#region Init
protected override void Start() {
base.Start();
//if (tracker == null)
// tracker = GetComponentInParent();
xrNode = isLeft ? XRNode.LeftHand : XRNode.RightHand;
device = InputDevices.GetDeviceAtXRNode(xrNode);
ShowModel(device.name);
InputDevices.deviceConnected += OnDeviceConnected;
InputDevices.deviceDisconnected += OnDeviceDisconnected;
}
///
/// Controller has connected
///
/// The InputDevice of the controller
protected virtual void OnDeviceConnected(InputDevice device) {
bool isLeft = (device.characteristics & InputDeviceCharacteristics.Left) != 0;
bool isController = (device.characteristics & InputDeviceCharacteristics.Controller) != 0;
if (isController && isLeft == this.isLeft) {
if (this.device.name != device.name)
ShowModel(device.name);
this.device = device;
Show(true);
}
}
///
/// Controller has disconnected
///
/// This also happens when the device is no longer tracked.
/// The InputDevice of the controller
protected virtual void OnDeviceDisconnected(InputDevice device) {
bool isLeft = (device.characteristics & InputDeviceCharacteristics.Left) != 0;
bool isController = (device.characteristics & InputDeviceCharacteristics.Controller) != 0;
if (isController && isLeft == this.isLeft) {
this.device = device;
Show(false);
}
}
#endregion
#region Update
public override void UpdateComponent() {
base.UpdateComponent();
status = Tracker.Status.Unavailable;
positionConfidence = 0;
rotationConfidence = 0;
if (device == null)
return;
status = Tracker.Status.Present;
Vector3 position;
if (device.TryGetFeatureValue(CommonUsages.devicePosition, out position)) {
transform.position = trackerTransform.TransformPoint(position);
positionConfidence = 1;
status = Tracker.Status.Tracking;
}
Quaternion rotation;
if (device.TryGetFeatureValue(CommonUsages.deviceRotation, out rotation)) {
transform.rotation = trackerTransform.rotation * rotation;
rotationConfidence = 1;
status = Tracker.Status.Tracking;
}
UpdateInput();
show = (status == Tracker.Status.Tracking);
}
protected virtual void UpdateInput() {
device.TryGetFeatureValue(CommonUsages.trigger, out trigger1);
device.TryGetFeatureValue(CommonUsages.grip, out trigger2);
bool buttonPress;
bool buttonTouch;
device.TryGetFeatureValue(CommonUsages.primaryButton, out buttonPress);
device.TryGetFeatureValue(CommonUsages.primaryTouch, out buttonTouch);
button1 = buttonPress ? 1 : buttonTouch ? 0 : -1;
device.TryGetFeatureValue(CommonUsages.secondaryButton, out buttonPress);
device.TryGetFeatureValue(CommonUsages.secondaryTouch, out buttonTouch);
button2 = buttonPress ? 1 : buttonTouch ? 0 : -1;
device.TryGetFeatureValue(CommonUsages.menuButton, out buttonPress);
option = buttonPress ? 1 : 0;
Vector2 axis;
float axisButton;
device.TryGetFeatureValue(CommonUsages.primary2DAxis, out axis);
device.TryGetFeatureValue(CommonUsages.primary2DAxisClick, out buttonPress);
device.TryGetFeatureValue(CommonUsages.primary2DAxisTouch, out buttonTouch);
axisButton = buttonPress ? 1 : buttonTouch ? 0 : -1;
primaryAxis = new Vector3(axis.x, axis.y, axisButton);
device.TryGetFeatureValue(CommonUsages.secondary2DAxis, out axis);
device.TryGetFeatureValue(CommonUsages.secondary2DAxisClick, out buttonPress);
device.TryGetFeatureValue(CommonUsages.secondary2DAxisTouch, out buttonTouch);
axisButton = buttonPress ? 1 : buttonTouch ? 0 : -1;
secondaryAxis = new Vector3(axis.x, axis.y, axisButton);
device.TryGetFeatureValue(CommonUsages.batteryLevel, out battery);
}
public void Show(bool showModel) {
if (model == null)
return;
if (!Application.isPlaying)
model.SetActive(showModel);
Renderer[] renderers = model.GetComponentsInChildren();
for (int i = 0; i < renderers.Length; i++)
renderers[i].enabled = showModel;
}
#endregion Init
#endif
}
}