#if pUNITYXR
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
using Passer.Tracking;
namespace Passer.Humanoid {
///
/// Universal API for tracking XR devices.
///
///
/// Setup
/// =====
/// Go to Edit Menu->Project Settings->XR Plugin Management and click on the Install XR Plugin Management button:
/// \image html UnityXRPreferences.png
/// Then enable the desired XR Plugin. For example the Oculus plugin for Android:
/// \image html UnityXRPreferencesOculus.png
/// Note that if you want to test Oculus Quest in the editor, the Oculus Plugin for Standalone needs to be enabled too:
/// \image html UnityXRPreferencesOculus2.png
///
/// Configuration
/// =============
/// To enable body tracking with Unity XR for a humanoid, Unity XR needs to be enabled
/// in the HumanoidControl component:
/// \image html UnityXRTrackerNotShown.png
/// By default the \ref Passer::Tracking::UnitXR "UnityXR" object is not visible in the scene,
/// but it will be created automatically when the scene starts.
/// If the button Show is pressed, the UnityXR object will be created in the Real World object.
/// \image html UnityXRTrackerShown.png
/// UnityXR (UnityXR) is a reference to the object in the scene representing the root of the Unit XR tracking space.
/// This GameObject is found as a child of the Real World GameObject.
/// The \ref Tracking::UnityXR "UnityXR" GameObject can be used to adjust the origin of the Unity XR tracking space.
///
/// Head %Target
/// ============
/// To use an HMD tracking for the head of the avatar Unity XR needs to be enabled on the Head %Target too.
/// This is enabled by default:
/// \image html UnityXRHeadSensorNotShown.png
/// By default the \ref Passer::Tracking::UnityXRHmd "UnityXRHmd" object is not visible in the scene,
/// but it will be created automatically when the scene starts.
/// The UnityXRHmd will also have the main camera attached. You can disable the camera
/// attached to the UnityXRHead object if needed, for example when you want to see the avatar's
/// movements in third person view.
/// If the button Show is pressed, the UnityXRHead object will be created as a child of
/// the UnityXR object in the Real World.
/// \image html UnityXRHeadSensorShown.png
///
/// Hand %Target
/// ============
/// When you want to control the hands of the avatar using Unity XR you need to enable Unity XR on the Hand %Target:
/// \image html UnityXRHandSensorNotShown.png
/// Like with the Head %Target, the \ref Passer::Tracking::UnityXRController "UnityXRController" object
/// is not visible in the editor scene by default but it will be created automatically when the scene starts.
/// If the button Show is pressed, the UnityXRController object will be creates as a child of
/// the UnityXR object in the Real World.
/// \image html UnityXRHandSensorShown.png
///
/// Hand %Tracking (Plus & Pro)
/// ==========================
/// Some devices support hand tracking in combination with UnityXR. Native hand tracking with Unity XR is
/// still not possible, so we provide specific implementations for the following hand tracking options
///
/// Oculus Quest
/// ------------
/// When the Android platform is selected in Unity, an additional option for Oculus Hand %Tracking is shown:
/// \image html UnityXROculusHandTracking.png
/// When enabled, hand tracking will be possible for this humanoid.
///
/// HTC Vive
/// --------
/// For Vive hand tracking, the Vive Hand %Tracking SDK version 0.9 or higher is required. You can download it here:
/// Vive Hand Tracking SDK.
/// When the HTC Vive Hand Tracking SDK is imported in the project on the Windows Standalone platform,
/// an option for HTC Vive Hand %Tracking is shown:
/// \image html UnityXRViveHandTracking.png
/// For Vive Hand tracking, the OpenVR Plugin for UnityXR is needed. OpenXR does not work with
/// Vive Hand %Tracking in version 1.0.0 of the SDK. This may be fixed in more recent versions.
/// The OpenVR Plugin is automatically installed when the SteamVR Plugin from the Asset Store is
/// imported in the project.
/// HTC Vive headsets like Vive Pre, Vive Pro and normal Vive are supported. HTC Vive Pro 2 is untested, but may work.
///
/// Note: if you get an error in the ViveSkeleton.cs code stating that ViveHandTracking is not defined,
/// you need to import the ViveHandTracking/ViveHandTracking.asmdef from the Humanoid Control package.
///
/// \sa UnityXRHead UnityXRHand Tracking::UnityXR Tracking::UnityXRHmd Passer::Tracking::UnityXRController
[System.Serializable]
public class UnityXRTracker : HumanoidTracker {
/// \copydoc HumanoidTracker::name
/// \copydoc HumanoidTracker::name
public override string name => "Unity XR";
/// \copydoc HumanoidTracker::headSensor
public override HeadSensor headSensor => humanoid.headTarget.unityXR;
/// \copydoc HumanoidTracker::leftHandSensor
public override ArmSensor leftHandSensor => humanoid.leftHandTarget.unityXR;
/// \copydoc HumanoidTracker::rightHandSensor
public override ArmSensor rightHandSensor => humanoid.rightHandTarget.unityXR;
[System.NonSerialized]
private HumanoidSensor[] _sensors;
public override HumanoidSensor[] sensors {
get {
if (_sensors == null)
_sensors = new HumanoidSensor[] {
headSensor,
leftHandSensor,
rightHandSensor
};
return _sensors;
}
}
#if hOCHAND
///
/// Enables hand tracking on the Oculus Quest
///
public bool oculusHandTracking = true;
#endif
#if hVIVEHAND
///
/// Enables hand tracking on the HTC Vive
///
public bool viveHandTracking = true;
#endif
#region Manage
public override void CheckTracker(HumanoidControl humanoid) {
CheckTracker(humanoid, UnityXR.Get);
}
#endregion
#region Start
public override void StartTracker(HumanoidControl humanoid) {
this.humanoid = humanoid;
UnityXRDevice.Start();
CheckTracker(humanoid);
headSensor.Start(humanoid, humanoid.headTarget.transform);
leftHandSensor.Start(humanoid, humanoid.leftHandTarget.transform);
rightHandSensor.Start(humanoid, humanoid.rightHandTarget.transform);
}
//public override bool AddTracker(HumanoidControl humanoid, string resourceName) {
// return false;
//}
#endregion
#region Update
public override void UpdateTracker() {
if (!enabled || trackerComponent == null)
return;
status = trackerComponent.status;
}
#endregion
public override void Calibrate() {
if (!enabled || trackerComponent == null)
return;
base.Calibrate();
trackerComponent.transform.position = trackerComponent.transform.position;
}
}
}
#endif