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
| Component | What it does | Works without VRChat? |
|---|---|---|
| Neuro Binder | UI Toolkit routing table: map EEG bands (Alpha, Focus_Ratio, etc.) to blendshapes or material properties via AnimationCurve | ✅ |
| Live Preview | Connects to the server in Edit mode, runs FFT, drives your avatar while you tune curves wearing the headset | ✅ |
| Neuro Reactor | Runtime MonoBehaviour that applies bindings in any standalone/XR Unity build | ✅ |
| VRChat SDK Automator | Generates clips + 1D blend tree, merges via Modular Avatar without mutating base FX | VRChat 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
- Open Unity 2022.3 LTS
- Go to Window → Package Manager
- Click + → Install package from git URL…
- Enter:
https://github.com/pieeg-club/PiEEG-unity.git?path=/Packages/com.pieeg.unityNo third-party runtime dependencies (uses System.Net.WebSockets.ClientWebSocket).
For VRChat users only
Install these dependencies:
- VRChat Avatars SDK 3.0 (opens in a new tab) (via VCC)
- Modular Avatar (opens in a new tab) (via VCC)
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
- Choose a Source (e.g.,
EEG_Alpha) - Set Target to:
- Blendshape: pick a SkinnedMeshRenderer + blendshape name
- Material Float: pick a Material + shader property
- Shape the Response Curve (default is linear 0→1)
Live preview
- Start PiEEG-server
- Press Start Live Preview in the Neuro Binder
- Watch the avatar react in Edit mode while you tune curves
Build mappings
- Press Build Mappings
- This writes
Assets/PiEEG/Generated/<Avatar>/PiEEG_FX.controller - Adds a
PiEEG Neurochild GameObject with Modular Avatar components - 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
| Source | Description |
|---|---|
EEG_Delta | 0.5–4 Hz (slow waves, deep sleep) |
EEG_Theta | 4–8 Hz (meditation, drowsiness) |
EEG_Alpha | 8–13 Hz (relaxed, eyes closed) |
EEG_Beta | 13–30 Hz (focus, active thinking) |
EEG_Gamma | 30–100 Hz (high cognition) |
EEG_Focus_Ratio | Beta / (Alpha + Theta) |
| Custom | Define 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:
- Open Window → General → Test Runner → EditMode
- 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
--oscflag:pieeg-server --osc - Check parameter names match:
/avatar/parameters/EEG_Alphaetc.
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
- Source: github.com/pieeg-club/PiEEG-unity (opens in a new tab)
- License: MIT
- Package name:
com.pieeg.unity
Related Documentation
- VRChat OSC Integration — Server-side OSC bridge configuration
- WebSocket API — Low-level protocol reference
- PiEEG Server Features — Server capabilities overview