A comprehensive Unity XR template designed specifically for Meta Quest research experiments. Build VR research applications with built-in support for hand tracking, eye tracking, face expression tracking, comprehensive data collection, and more.
β οΈ Note: This project is still under construction. For inquiries, help, or support, please contact: resxr.toolkit@gmail.com
ResXR is a complete framework for building VR research applications on Meta Quest headsets. It provides:
- Hand Tracking & Gesture Recognition - Full hand tracking with pinch detection
- Eye Tracking & Gaze Analysis - Real-time eye gaze tracking and focused object detection
- Face Expression Tracking - Face expression weights and validity tracking
- Comprehensive Data Collection - Automatic CSV export of all tracking data
- Scene Management - Additive scene loading with smooth transitions
Unlike other solutions that provide black-box classes, ResXR is designed as a transparent, clear box where researchers own and modify every part of their experiment. The template provides structure, base classes, and examples, but you are expected to copy, modify, and customize the code for your specific research needs. Everything is open and transparent - you understand exactly how your experiment runs under the hood.
- Unity 2021.3 or later
- Meta Quest SDK (OVR) - Automatically installed via Unity Package Manager (see below)
- Meta Quest headset (Quest 2, Quest Pro, Quest 3)
- Basic knowledge of Unity and C#
- Click the "Use this template" button on GitHub
- Create a new repository with your desired name
- Clone your new repository locally:
git clone <your-repository-url>
cd <your-repository-name>- Open Unity Hub
- Click "Add" and select the cloned project folder
- Unity will detect the project and open it
This project requires the Meta XR SDK, which is automatically installed via Unity Package Manager based on package dependencies defined in Packages/manifest.json. The SDK itself is not included in this repository. When you open the project in Unity for the first time, Unity will automatically download and install the required Meta XR packages (version 78.0.0).
- Navigate to
Assets/Project Folder/ - Duplicate
New ResXRScene [Duplicate].unity - Rename it to your experiment name
- Add it to Build Settings (after Base Scene)
- Important: The Base Scene must be opened with your experiment scene additively. The Base Scene contains the player (
ResXRPlayer) and data manager (ResXRDataManager_V2) which run continuously throughout your experiment, even when scenes are changed. Your experiment scene will be loaded additively on top of the Base Scene. - Edit the
SceneReferencerand Flow Management scripts (SessionManager, TaskManager, TrialManager) directly to add your experiment references and logic - Build and run!
Assets/ResXR/
βββ Base Scene/ # Core persistent scene and systems
β βββ ResXRPlayer/ # Player controller, hand/eye/face tracking
β βββ ResXRDataManager_V2/# Data collection and export system
β βββ SceneManagement/ # Scene loading and transitions
β βββ ResXR_RoomCalibrator/# Room-scale calibration
βββ Flow Management/ # Session/Task/Trial flow control
βββ Utilities/ # Helper scripts and utilities
β βββ EditorUtilities/ # Editor tools
β βββ General Scripts/ # Singleton, utilities, extensions
βββ Detectors/ # Interaction detection system
βββ Demo Experiments/ # Example implementations
β βββ Binary Choice/ # Two-choice decision experiment
β βββ Maze/ # Navigation experiment
β βββ Museum/ # Art viewing experiment
βββ Meta components/ # Meta-specific integrations
- Automatic Continuous Data: Head, hands, eyes, body, face tracking at 50Hz
- Gaze: Combined (cyclopean) gaze hit point and focused object always recorded when eye tracking is on. Optional per-eye hit points and focused objects (left/right) via the "Include Separate Eyes Gaze" recording optionβenables 3 raycasts per frame instead of 1; turn off in heavy scenes to save performance.
- Custom Event Logging: Create custom data classes for experiment-specific events
- Events table (
Events.csv): Template providesReportEventrows withname,onset, andduration(seconds). UseTime.realtimeSinceStartupforonsetto match continuous data and downstream pipelines; callResXRDataManager_V2.Instance.ReportEvent(...). - CSV Export: All data exported to organized CSV files
- Metadata: Automatic session metadata generation (supports later Motion-BIDS export; includes device offset, tracking origin, reference frames;
build_info_availableflags whether build provenance fields are present, otherwise they are left empty)
While every VR app has tracking, ResXR provides a simple, unified API through ResXRPlayer singleton that gives you easy access to all tracking components without digging through OVR internals:
- Hand Tracking:
ResXRPlayer.Instance.HandLeft/HandRight- Direct access to hand tracking, pinch detection, and finger colliders - Eye Tracking:
ResXRPlayer.Instance.FocusedObject,EyeGazeHitPosition(combined gaze, always when both eyes confident). Per-eye:LeftEyeGazeHitPosition,RightEyeGazeHitPosition,LeftFocusedObject,RightFocusedObject,HasLeftEyeHit,HasRightEyeHitwhen the separate-eyes recording option is enabled. The Data Manager sets whether ResXREyeTracker runs 1 raycast (combined only) or 3 (left, right, combined) via that option. - Face Tracking:
ResXRPlayer.Instance.OVRFace- Direct access to face expression weights and validity (OVRFaceExpressions is on the ResXRPlayer prefab and assigned in the Inspector) - Body Tracking: Body joint positions and calibration
- Player Transforms:
PlayerHead,RightHand,LeftHand- Easy access to player transforms - Input Managers:
ControllersInputManager,PinchingInputManager- Unified input handling
See ResXRPlayer.cs for the complete API. Access everything through ResXRPlayer.Instance - no need to find OVR components manually!
- Additive Loading: Experiment scenes are loaded additively on top of the Base Scene, which must remain open throughout your experiment
- Persistent Base Scene: The Base Scene contains the player (
ResXRPlayer) and data manager (ResXRDataManager_V2) that run continuously, even when switching between experiment scenes - Smooth Transitions: Automatic fade effects during scene changes
- Player Repositioning: Automatic player positioning per scene
- Pinching: Hand-based pinch interaction with priority-based selection
- Controllers: Quest controller input with haptic feedback
- Touch: Collider-based touch detection
- Hierarchical Structure: Session β Task β Trial organization
- Edit the scripts directly: Flow Management scripts (
SessionManager,TaskManager,TrialManager) are intentionally simple stubs you modify directly for your experiment. They are part of the clear-box philosophy: you own them and edit them. By default some methods are placeholders; implement your own Start/End/Between logic directly in the scripts. The demo experiments ship with copies named e.g.Maze_SessionManagerfor convenience when including multiple experiments in one project. - Clear Ownership: You own and modify your experiment code
- Full Component Documentation - Comprehensive guide to all components
- Data Manager Documentation - Data collection system details
- Demo Experiments - Working examples in
Assets/ResXR/Demo Experiments/
The template includes three complete demo experiments:
- Binary Choice - Two-choice decision-making experiment
- Maze - Navigation experiment with coin collection
- Museum - Art viewing experiment with gaze tracking
Each demo shows:
- Flow Management structure (Session/Task/Trial)
- Custom data logging
- Interaction patterns
- Scene organization
- Read the Documentation - Start with
ResXR_Template_Documentation.md - Explore Demo Experiments - See working examples in
Assets/ResXR/Demo Experiments/ - Duplicate the Template Scene - Use
Assets/Project Folder/New ResXRScene [Duplicate].unity - Modify Directly - Own your experiment code - modify scripts directly
- Build Your Experiment - Add your research logic to the template structure
// Access player instance
ResXRPlayer player = ResXRPlayer.Instance;
// Fade to black
await player.FadeViewToColor(Color.black, 1.0f);
// Check if player is looking at something
if (player.FocusedObject != null)
{
Debug.Log($"Looking at: {player.FocusedObject.name}");
}
// Wait for pinch gesture
await player.PinchingInputManager.WaitForHoldAndRelease(HandType.Right, 1.0f);
// Pipeline-friendly event marker (Events.csv); onset uses same clock as continuous CSVs
ResXRDataManager_V2.Instance.ReportEvent("stimulus_on", Time.realtimeSinceStartup, 0f);
// Choice trials: see LogChoice on ResXRDataManager_V2 for the full signature
// Switch scenes
await ResXRSceneManager.Instance.SwitchActiveScene("NextExperimentScene");-
Duplicate
Assets/Project Folder/New ResXRScene [Duplicate].unity -
Rename to your experiment name
-
Add to Build Settings (after Base Scene)
-
Scene Architecture: The Base Scene and your experiment scene must be opened additively together. The Base Scene contains:
ResXRPlayer- Player controller with hand/eye/face trackingResXRDataManager_V2- Data collection system- Other core systems that persist throughout your experiment
These systems run continuously and remain active even when you switch between experiment scenes. Your experiment scene is loaded additively on top of the Base Scene, allowing you to change experiment content while keeping the player and data collection systems running.
Open SceneReferencer.cs and add your experiment references:
public class SceneReferencer : ResXRSingleton<SceneReferencer>
{
[Header("My Experiment Objects")]
public GameObject stimulus;
public InstructionsPanel instructions;
public Transform targetPosition;
[Header("Configuration")]
public float trialDuration = 10f;
}The Flow Management scripts in Assets/ResXR/Flow Management/ are template stubs you edit directly. Add SessionManager, TaskManager, and TrialManager to your scene and implement StartSession, EndSession, BetweenTasksFlow, StartTrial, EndTrial, etc. in those scripts. The demo experiments use renamed copies (e.g. Maze_SessionManager) only for convenience when shipping multiple experiments in one project.
// Open SessionManager.cs (and TaskManager.cs, TrialManager.cs) and implement the placeholder methods
// Add the components to a GameObject in your experiment scene and configure tasks/trials in the Inspector- Edit the Flow Management scripts to add your Start/End/Between logic
- Configure tasks and trials in the Inspector
- Add custom data classes for logging
- Implement your experiment-specific logic directly in SessionManager, TaskManager, and TrialManager
This is a research template. Contributions, improvements, and feedback are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
This project is licensed under the Apache License, Version 2.0.
This project requires the Meta XR SDK, which is automatically installed via Unity Package Manager based on package dependencies defined in Packages/manifest.json. The SDK itself is not included in this repository.
The Meta XR SDK is provided by Meta Platform Technologies, LLC and its affiliates, and is licensed under the Meta SDK License Agreement. The Meta XR SDK is not covered by the Apache License 2.0 and is subject to its own license terms.
Additional third-party components (including open-source Unity plugins vendored under Assets/, such as UniTask, NaughtyAttributes, and DOTween) are listed with license notes in THIRD_PARTY_NOTICES.md.
ResXR builds upon the early work of the TAUXR Research Template, developed by the TAU-XR Studio and talmzip.
Thanks to the authors of open-source tools used in this template, including UniTask (Cysharp), NaughtyAttributes (Denis Rizov / community), and DOTween (Demigiant), as well as other dependencies documented in THIRD_PARTY_NOTICES.md.
We would like to thank the original contributors and developers for their work on the initial template, which helped shape the early direction of this project.
For questions, issues, or inquiries:
- Email: resxr.toolkit@gmail.com
- Check the Full Documentation
- Review the Demo Experiments for examples
- Examine the source code (it's all transparent!)
- Own Your Code - Edit the Flow Management scripts (SessionManager, TaskManager, TrialManager) directly; they are stubs you implement for your experiment
- Understand the System - Read the code to understand how it works
- Use Demo Experiments - Learn from working examples
- Log Everything - Use ResXRDataManager_V2 for all experiment data
- Follow Flow Hierarchy - Use Session β Task β Trial structure
- Keep It Transparent - All code is open - understand and customize
Remember: ResXR is a "clear box" template. You own and modify your experiment code. Everything is transparent and open for you to understand and customize.