PlatformScience & ResearchPricingDevelopersCompanySign inGet started
HarmonEyes
Platform Science & Research Pricing Developers Company
Sign in Get started
Developers/Unity SDK

Unity SDK

Turn raw eye-tracking from a headset or webcam into four real-time capabilities inside Unity. Ships native libraries, a C# wrapper, sample scenes for Meta Quest Pro and HTC Vive Focus Vision, and a headset-free mock player.

Install Getting started API reference
Naming: the SDK exposes the platform’s Cognitive Load capability under the code name MentalWorkload (MentalWorkloadData, OnMentalWorkloadResult). Fatigue, Attention, and Mental Readiness use their platform names. Code identifiers below are shown verbatim.
Install

Install the Unity SDK

Step 1 · Install dependencies

Install the base dependencies if they are not already present.

TextMeshPro (com.unity.textmeshpro) ships with Unity. No separate install needed. The first time a scene requires TMP, click Import TMP Essentials when prompted.

Step 2 · Download the package

https://github.com/harmoneyes/HarmonEyesSDK/raw/main/HarmonEyesSDK.unitypackage

Step 3 · Import into Unity

In Unity, choose Assets › Import Package › Custom Package… and open the HarmonEyesSDK.unitypackage you downloaded. Leave all boxes checked and click OK.

Mock Tracker sample

The SDK ships with a Mock Tracker sample that lets you exercise the SDK and validate your license key without a Vive or Meta Quest Pro headset connected. It can also replay CSV recordings captured by the Vive or Meta sample collectors, so you can re-run the SDK against a known data stream.

  1. Open Assets/HarmonEyesSDK/Samples/HarmonEyesMockTrackerSample/Scenes/HarmonEyesMockTrackerSampleScene.
  2. Select the EyeTrackingDataMockAnalyzer prefab and enter your license key in the EyeTrackingConfig component.
  3. On the same prefab, the MockEyeTrackingCollectingData component exposes a “Session Csv” slot. A bundled CSV (eyetrackingsample_meta_quest_pro.csv) is assigned by default; drag in your own recording to replay it.
  4. The “Playback Speed Multiplier” (1×–20×) controls how fast rows are emitted, and higher values compress wall-clock time so the time-gated capabilities (Fatigue, Mental Readiness) reach their thresholds faster during testing.
  5. Select the appropriate eye-tracker type in the AnalyzeEyeTrackingData component (defaults to Pupil Labs to match the sample CSV).
  6. Press Play. The in-scene text fields display Cognitive Load, Fatigue, Attention, and Mental Readiness, confirming the SDK is loaded and the license key validated.
Getting started

Overview & integration

The Unity SDK turns raw eye-tracking data from a supported headset or webcam into four real-time capabilities: Cognitive Load, Fatigue, Attention, and Mental Readiness. It is delivered as a Unity package: a native theia library, a C# wrapper, three platform sample scenes (Meta Quest Pro, HTC Vive Focus Vision, and a headset-free Mock player), and editor scripts.

What it produces

Capability Levels Cadence Key payload fields
Cognitive LoadLow / Moderate / Highper native batch (~1s)level, confidence, prob_high, batch_number
FatigueAlert / Neither / RatherDrowsy / Drowsyper native batch (~1s)level, confidence, batch_number, ttt_level, ttt_minutes
AttentionNarrow / Mod-Narrow / Neither / Mod-Broad / Broadcontinuouslevel, label, composite_score, total_observations
Mental Readinesslow % / moderate % / high %once min session length metlow_percentage, moderate_percentage, high_percentage, total_predictions

Supported hardware

Tracker Native preset Sample scene
Meta Quest ProQuest (72 Hz)Meta Quest Pro sample
HTC Vive Focus VisionQuest preset (closest match)Vive Focus Vision sample
Pupil Labs NeonPupilLabs (200 Hz)Mock Tracker sample (CSV playback)
Webcam desktop trackersWebcam (30 Hz)
GanzinGanzin (60 Hz)

For any tracker not listed, select the nearest lower-Hz preset.

Get a license key

A license key is required. Contact us to obtain one. The same key is entered on the AnalyzeEyeTrackingData component in each sample scene.

Three ways to use the SDK

Headset sample
You have a Meta Quest Pro or Vive Focus Vision and want a working scene out of the box.
Headset-free Mock playback
You don’t have a headset, or you want to test against a recorded CSV.
Custom collector script
Your platform isn’t covered by the bundled samples. Write a gaze-collection and submission script for your tracker (below).

Manual integration

A custom integration is three steps.

1 · Initialise

Add the AnalyzeEyeTrackingData component to a GameObject, enter the license key, and pick the tracker preset that matches your hardware (or the closest sample-rate match, rounding down). The component handles native SDK creation, license validation, and session start automatically on Start. Read AnalyzeEyeTrackingData.Instance.EyeTrackingInitCompleted to know when initialisation has completed.

2 · Capture: submit one sample per tracker frame
using UnityEngine;
using HarmonEyes.EyeTracking.Common;

public class MyCollector : MonoBehaviour
{
    [SerializeField] private Camera headCamera;

    void FixedUpdate()
    {
        var analyze = AnalyzeEyeTrackingData.Instance;
        if (analyze == null || !analyze.EyeTrackingInitCompleted) return;

        long timestampNs = (long)(Time.timeAsDouble * 1e9);

        // Pull per-eye origin, orientation, closed-weight and a blink
        // decision from your platform's API.
        Vector3    leftEyeOrigin       = Vector3.zero;
        Quaternion leftEyeOrientation  = Quaternion.identity;
        float      leftEyeClosed       = 0f;
        Vector3    rightEyeOrigin      = Vector3.zero;
        Quaternion rightEyeOrientation = Quaternion.identity;
        float      rightEyeClosed      = 0f;
        bool       isBlinking          = false;

        Sample s = GazeDataSampleFactory.CreateGazeSample(
            analyze.SessionId, timestampNs,
            leftEyeOrigin,  leftEyeOrientation,  leftEyeClosed,
            rightEyeOrigin, rightEyeOrientation, rightEyeClosed,
            headCamera.fieldOfView,
            isBlinking);

        analyze.SubmitGazeSample(s);
    }
}
3 · Process: read results

Polling: read the latest payload on demand:

var mw = analyze.EyeTrackingAnalyzer.CurrentMentalWorkload;   // Cognitive Load
if (mw != null) Debug.Log($"Cognitive Load: {mw.LevelName} (conf {mw.confidence:F2})");

Event-driven: subscribe once, react to each new prediction:

analyze.EyeTrackingAnalyzer.OnMentalWorkloadResult += mw =>
    Debug.Log($"Cognitive Load: {mw.LevelName} (conf {mw.confidence:F2})");
API reference

API reference

Real-time Cognitive Load, Fatigue, Attention, and Mental Readiness from eye-tracking hardware. Every type below lives in the HarmonEyes.EyeTracking.Common namespace.

Analysis outputs

Cognitive Load and Fatigue refresh once per second (edge-triggered when a new native batch arrives); Attention updates continuously as fixations and saccades accumulate; Mental Readiness is computed on demand from accumulated Cognitive Load predictions. Each payload carries a monotonically increasing counter (batch_number, total_observations, or total_predictions) so consumers can edge-trigger UI updates.

Scene setup

  1. Add AnalyzeEyeTrackingData to a GameObject, which holds SDK config and the latest predictions, and runs the once-per-second submission of accumulated gaze samples to the native SDK.
  2. Enter your license key in the LicenseKey field. It is validated synchronously during Start(); success or failure is logged to the Unity console.
  3. Add a platform-specific collector that submits samples into Instance.EyeTrackingData.Samples each tracker frame.

License validation

On scene start, validation happens automatically. Two boolean flags expose the outcome:

if (AnalyzeEyeTrackingData.Instance.LicenseKeyValidated) { /* SDK is live; start submitting samples */ }
if (!AnalyzeEyeTrackingData.Instance.EyeTrackingInitCompleted) { /* missing/invalid key */ }

Submitting eye-tracking data

Per-frame eye data is built into a neutral Sample via GazeDataSampleFactory.CreateGazeSample, then submitted via SubmitGazeSample. Accumulated samples are pushed to the native SDK once per second. The factory projects each eye’s gaze ray onto a 1600×1200 virtual screen at 600 mm using the supplied FOV.

Accessing results

Subscribe to callbacks, or poll the Current* properties (all nullable, so null-check before use).

var a = AnalyzeEyeTrackingData.Instance.EyeTrackingAnalyzer;
a.OnMentalWorkloadResult  += mw  => Debug.Log(mw.LevelName);   // Cognitive Load
a.OnFatigueResult         += fat => Debug.Log(fat.LevelName);
a.OnAttentionResult       += att => Debug.Log(att.label);
a.OnMentalReadinessResult += mr  => Debug.Log($"low {mr.low_percentage:F0}% / high {mr.high_percentage:F0}%");
a.CurrentMentalWorkload    // MentalWorkloadData,   nullable  (Cognitive Load)
a.CurrentFatigue           // FatigueData,          nullable
a.CurrentAttention         // AttentionData,        nullable
a.CurrentMentalReadiness   // MentalReadinessData,  nullable

Class reference

AnalyzeEyeTrackingData

Scene-level singleton MonoBehaviour. Owns the native SDK lifecycle and the 1 Hz analyzer pump. Exactly one instance must exist in the scene.

Inspector field Type Description
LicenseKeystringYour HarmonEyes license key. Required. Validated synchronously in Start().
TrackerTrackerTypeNative preset. Default Quest. Values: Nexus (Webcam 30 Hz), Ganzin (60 Hz), Quest (72 Hz, also Vive Focus Vision), PupilLabs (200 Hz). Pick the closest sample rate, rounding down.
logMentalWorkload, logFatigue, logAttention, logMentalReadinessboolWhen true, writes each new prediction for that capability to the Unity console.
Property Type Description
InstancestaticIn-scene singleton and interface to the SDK.
EyeTrackingInitCompletedboolTrue once the SDK is ready to accept samples.
LicenseKeyValidatedboolTrue if the license key passed validation.
EyeTrackingDataEyeTrackingDataShared per-session buffer of collected Samples.
CurrentMentalWorkload / CurrentFatigue / CurrentAttention / CurrentMentalReadinessnullableLatest prediction for each capability (on EyeTrackingAnalyzer). Null until the first result arrives.
GazeDataSampleFactory

Static class. Builds Sample records; hides the XY projection, per-session blink-ID iteration, and pupil-diameter computation.

public static Sample CreateGazeSample(
    string sessionId, long timestampNs,
    Vector3 leftEyeOrigin, Quaternion leftEyeOrientation,
    Vector3 rightEyeOrigin, Quaternion rightEyeOrientation,
    float fovDeg, bool isBlinking,
    double pupilDiameterLeft = 0.0,
    double pupilDiameterRight = 0.0);

Returns a Sample populated with the timestamp, left/right eye screen XY (pixels), optional pupil diameters, and a monotonic blink ID. EndSession(string sessionId) clears the per-session blink-ID counter, an optional cleanup when many sessions run in one app.

EyeTrackingAnalyzer

Thin C# wrapper around the native theia C API, managed by AnalyzeEyeTrackingData. Documented for advanced users. Normal integrations don’t call it directly.

GetCurrentMentalWorkload/Fatigue/Attention/MentalReadiness(EyeTrackingData)
Return the latest prediction for each capability, or null if none yet. All four call the same push path internally — call one per 1 Hz tick.
SetMentalReadinessMinSessionSeconds(double)
Override the minimum session length before Mental Readiness returns a result. Returns 0 on success, -1 if the SDK isn’t created. Typically used to shorten the gate during dev testing.
IsRunning()
True when the native SDK has an active session. Useful as a precondition before submitting samples.
FeatureVersion()
Returns the native feature/model-bundle version string. Useful for diagnostics and bug reports.
GetLicenseInfo()
Returns a snapshot of the validated license — id, status, expiry, validated-at, cached flag, and entitlements.
Sample

One frame of eye data in the neutral shape the analyzer consumes. Build with CreateGazeSample.

Field Type Description
timestampNslongMonotonic timestamp in nanoseconds relative to session start.
leftEyeX, leftEyeY, rightEyeX, rightEyeYfloatPer-eye gaze point in virtual-screen pixels (0–1600, 0–1200). Zero during blink frames.
pupilDiameterLeft, pupilDiameterRight, pupilDiameterdoublePupil diameters in mm. 0 if unknown.
blinkIdintMonotonic per-blink ID during a blink (1, 2, 3…); -1 when not blinking.
Result data classes
Class Capability Fields
MentalWorkloadDataCognitive Loadlevel (0/1/2), confidence, batch_number, LevelName ("Low"/"Moderate"/"High")
FatigueDataFatiguelevel (0–3), confidence, batch_number, ttt_level, ttt_minutes, LevelName
AttentionDataAttentionlevel (1–5), label, composite_score (0–1), total_observations
MentalReadinessDataMental Readinesslow_percentage, moderate_percentage, high_percentage, total_predictions

Start building today.

Free developer tier, full SDK access, no credit card to start.

Get startedBack to Developers
HarmonEyes

The foundation model for human-state intelligence, measured from eye movement alone.

HarmonEyes technology is patented. Privacy statement: the HarmonEyes service does not record, collect or store any personal user data or eye-tracking data. Bethesda, Maryland, USA · sales@harmoneyes.com
© 2026 RightEye, LLC (dba HarmonEyes) X LinkedIn Terms of Use Privacy Policy