Software
Integrations
Unity Plugin

PiEEG Unity Plugin

Stream live EEG from PiEEG-server into Unity and build no-code neuro-reactive avatars. Map EEG bands to blendshapes or shader properties with a visual routing table, preview with live signals in the editor, and deploy to VRChat or any Unity project.

Current version: 0.2.0
Requires: Unity 2022.3+ • PiEEG-server running
VRChat users need: VRChat Avatars SDK 3.0 (opens in a new tab) + Modular Avatar (opens in a new tab)

Features

ComponentWhat it doesWorks without VRChat?
Neuro BinderUI Toolkit routing table: map EEG bands (Alpha, Focus_Ratio, etc.) to blendshapes or material properties via AnimationCurve
Live PreviewConnects to the server in Edit mode, runs FFT, drives your avatar while you tune curves wearing the headset
Neuro ReactorRuntime MonoBehaviour that applies bindings in any standalone/XR Unity build
VRChat SDK AutomatorGenerates clips + 1D blend tree, merges via Modular Avatar without mutating base FXVRChat only

The band-power math (radix-2 FFT, Hanning window, rolling-max normalization, δ/θ/α/β/γ) is a faithful port of the server's spectral pipeline — what you preview is what OSC delivers.

Installation

Install via Unity Package Manager

  1. Open Unity 2022.3 LTS
  2. Go to Window → Package Manager
  3. Click + → Install package from git URL…
  4. Enter:
https://github.com/pieeg-club/PiEEG-unity.git?path=/Packages/com.pieeg.unity

No third-party runtime dependencies (uses System.Net.WebSockets.ClientWebSocket).

For VRChat users only

Install these dependencies:

The VRChat assembly compiles only when both are detected (gated by assembly defineConstraints), so the package imports cleanly in plain Unity projects too.

Quick Start — VRChat

Select your avatar

Choose the GameObject with a VRC Avatar Descriptor component.

Add Neuro Binder

Add PiEEG → Neuro Binder component (via Add Component), or open Window → PiEEG → Neuro Binder and it adopts the current selection.

Add a mapping

  1. Choose a Source (e.g., EEG_Alpha)
  2. Set Target to:
    • Blendshape: pick a SkinnedMeshRenderer + blendshape name
    • Material Float: pick a Material + shader property
  3. Shape the Response Curve (default is linear 0→1)

Live preview

  1. Start PiEEG-server
  2. Press Start Live Preview in the Neuro Binder
  3. Watch the avatar react in Edit mode while you tune curves

Build mappings

  1. Press Build Mappings
  2. This writes Assets/PiEEG/Generated/<Avatar>/PiEEG_FX.controller
  3. Adds a PiEEG Neuro child GameObject with Modular Avatar components
  4. Upload as usual — nothing in your base FX changed

On the server, run the OSC/VRChat bridge so it emits /avatar/parameters/EEG_<Band> (0–1). The parameter names registered by the Automator match exactly.

Quick Start — Any Unity Project

For desktop, mobile, or XR experiences (no VRChat):

Add components

Add both Neuro Binder + Neuro Reactor to a GameObject.

Wire bindings

Create mappings the same way as VRChat (source → target → curve).

Runtime

The Reactor applies bindings at runtime and in Edit mode automatically.

Available EEG Sources

SourceDescription
EEG_Delta0.5–4 Hz (slow waves, deep sleep)
EEG_Theta4–8 Hz (meditation, drowsiness)
EEG_Alpha8–13 Hz (relaxed, eyes closed)
EEG_Beta13–30 Hz (focus, active thinking)
EEG_Gamma30–100 Hz (high cognition)
EEG_Focus_RatioBeta / (Alpha + Theta)
CustomDefine in server config

All sources are normalized 0–1 via rolling-max with configurable window (default 10 seconds).

Raw Stream API

If you need frame-level access instead of band powers:

using PiEEG.Unity;
using UnityEngine;
 
public class BrainDemo : MonoBehaviour
{
    public PiEEGStream stream;
    
    void OnEnable()  => stream.OnFrame += HandleFrame;
    void OnDisable() => stream.OnFrame -= HandleFrame;
    
    void HandleFrame(PiEEGFrame frame)
    {
        // frame.channels[i] = µV
        // frame.t = unix timestamp (seconds)
        // frame.n = sample index
        float ch0 = frame.channels[0];
        transform.localScale = Vector3.one * (1f + Mathf.Abs(ch0) * 0.001f);
    }
}

Testing

The package includes hardware-free unit tests:

  1. Open Window → General → Test Runner → EditMode
  2. Run SpectralTests

These feed synthetic sine waves and assert the band-power pipeline (FftEngine, BandPowerAnalyzer, RollingNormalizer, NeuroBinding) behaves like the server.

End-to-end testing (with hardware) follows the Quick Start flow above.

Architecture

┌─────────────────┐
│  PiEEG-server   │  ← WebSocket (ws://raspberrypi.local:1616)
└────────┬────────┘
         │ JSON frames { t, n, channels: [...] }

┌─────────────────┐
│  PiEEGStream    │  ← C# WebSocket client (ClientWebSocket)
└────────┬────────┘
         │ OnFrame event

┌─────────────────┐
│  FftEngine      │  ← 256-sample FFT, Hanning window
└────────┬────────┘
         │ Spectral bins

┌─────────────────┐
│ BandPowerAnalyzer│ ← Log power per band (δθαβγ)
└────────┬────────┘
         │ Raw band powers

┌─────────────────┐
│ RollingNormalizer│ ← 10s rolling max → [0,1]
└────────┬────────┘
         │ Normalized floats

┌─────────────────┐
│  NeuroBinding   │  ← AnimationCurve → target value
└────────┬────────┘

    ┌────┴────┐
    ↓         ↓
Blendshape  Material.SetFloat()

Troubleshooting

Live preview not connecting

  • Verify PiEEG-server is running: pieeg-server (default port 1616)
  • Check WebSocket URL in Neuro Binder (default: ws://raspberrypi.local:1616)
  • Ensure firewall allows WebSocket connections

VRChat parameters not updating

  • Enable OSC in VRChat: Options → OSC → Enable
  • Run server with --osc flag: pieeg-server --osc
  • Check parameter names match: /avatar/parameters/EEG_Alpha etc.

Build Mappings button grayed out

  • Ensure VRChat SDK and Modular Avatar are installed
  • Select a GameObject with VRC Avatar Descriptor
  • Check Unity version is 2022.3+

Repository & License

Related Documentation