Python (ipin_vr/export.py): - generate_bank(): levels 1–2 enumerated exhaustively (120/720 combos), level 3 random with dedup; all deduplicated per-level - run_export(): CLI --per-level / --out / --seed flags per ONDEVICE §4.1 - cli.py routes "export" subcommand before session args (backward-compat) - 14 new tests: format, dedup for all 3 levels, space caps (L1=120, L2=720), seed determinism, file output Unity scaffold (ondevice/Scripts/): - CommandBank.cs: loads commands.json from StreamingAssets (WebRequest on Android) - TtsManager.cs: sherpa-onnx integration with [SHERPA] stubs, StreamingAssets→ persistentDataPath copy, defensive Speak() with onDone callback - SessionController.cs: passthrough flow §6, level switching, busy guard on Next - ondevice/README.md: full manual Editor steps §5 (Unity setup, Meta XR SDK, sherpa-onnx install, scene wiring, font, build, metrics) pytest: 37/37 passed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
194 lines
6.1 KiB
Markdown
194 lines
6.1 KiB
Markdown
# ondevice — składanie projektu Unity (PoC-1, Meta Quest 3)
|
|
|
|
Skrypty C# w `Scripts/` są gotowe do podpięcia. Poniżej lista ręcznych kroków
|
|
w Unity Editorze (nie da się ich wygenerować plikami). Odpowiada §5 z `docs/ONDEVICE.md`.
|
|
|
|
---
|
|
|
|
## 0. Wymagania wstępne
|
|
|
|
| Narzędzie | Wersja |
|
|
|---|---|
|
|
| Unity | 2022 LTS (6000.x) lub 2023 LTS |
|
|
| Android Build Support + OpenJDK | przez Unity Hub |
|
|
| Meta XR SDK | aktualny (via Package Manager → Add by git URL) |
|
|
| sherpa-onnx Unity plugin | patrz krok 4 |
|
|
| TextMeshPro | com.unity.textmeshpro (wbudowany w Unity) |
|
|
|
|
---
|
|
|
|
## 1. Nowy projekt Unity
|
|
|
|
1. Utwórz projekt **3D (URP)** lub **3D (Built-in)**.
|
|
2. Otwórz **Edit → Project Settings → Player → Android**:
|
|
- Target Architecture: **ARM64**
|
|
- Minimum API: **29** (Quest 3)
|
|
- Target API: **32** (lub latest)
|
|
3. Otwórz **Edit → Project Settings → XR Plug-in Management → Android**:
|
|
- Zaznacz **OpenXR**
|
|
- W zakładce OpenXR dodaj **Meta Quest feature set**
|
|
4. Otwórz **Edit → Project Settings → XR Plug-in Management → OpenXR**:
|
|
- Zaznacz **Meta Quest Support** i **Hand Tracking Subsystem** (opcjonalnie).
|
|
|
|
---
|
|
|
|
## 2. Meta XR SDK — passthrough
|
|
|
|
1. W **Package Manager** dodaj Meta XR SDK:
|
|
```
|
|
https://npm.developer.oculus.com (scope: com.meta.xr)
|
|
```
|
|
Zainstaluj: **Meta XR All-in-One SDK** lub minimum **Meta XR Core SDK**.
|
|
2. Utwórz scenę z **OVRCameraRig** (lub użyj prefabu z SDK).
|
|
3. Na `OVRManager` włącz **Passthrough Support = Required**.
|
|
4. Dodaj komponent **OVRPassthroughLayer** do kamery (Type: Underlay).
|
|
|
|
---
|
|
|
|
## 3. Bank poleceń — generowanie i import
|
|
|
|
```bash
|
|
# W repo ipin-vr (Python):
|
|
python -m ipin_vr export --per-level 300 --out commands.json --seed 42
|
|
```
|
|
|
|
Następnie:
|
|
1. Utwórz katalog **Assets/StreamingAssets/** (jeśli nie istnieje).
|
|
2. Skopiuj `commands.json` do **Assets/StreamingAssets/commands.json**.
|
|
|
|
---
|
|
|
|
## 4. sherpa-onnx — instalacja wtyczki i modelu głosu
|
|
|
|
### 4a. Wtyczka
|
|
|
|
Wybierz jedną z opcji:
|
|
|
|
**Opcja A — ręczne .aar/.dll z wydania sherpa-onnx:**
|
|
1. Pobierz z https://github.com/k2-fsa/sherpa-onnx/releases pliki dla Unity
|
|
(szukaj `unity-*` w Assets danego wydania).
|
|
2. Umieść `.dll` (Windows/Editor) i `.aar` (Android) w `Assets/Plugins/`.
|
|
|
|
**Opcja B — pakiet UPM (community):**
|
|
```
|
|
https://github.com/EitanWong/com.eitan.sherpa-onnx-unity.git
|
|
```
|
|
Dodaj przez **Package Manager → Add package from git URL**.
|
|
|
|
### 4b. Model głosu polskiego
|
|
|
|
1. Pobierz `vits-piper-pl_PL-gosia-medium.tar.bz2` z:
|
|
https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models
|
|
2. Rozpakuj — otrzymasz katalog `vits-piper-pl_PL-gosia-medium/` zawierający:
|
|
- `pl_PL-gosia-medium.onnx`
|
|
- `tokens.txt`
|
|
- `espeak-ng-data/` (katalog)
|
|
3. Skopiuj cały katalog do **Assets/StreamingAssets/**:
|
|
```
|
|
Assets/StreamingAssets/
|
|
commands.json
|
|
vits-piper-pl_PL-gosia-medium/
|
|
pl_PL-gosia-medium.onnx
|
|
tokens.txt
|
|
espeak-ng-data/
|
|
```
|
|
|
|
### 4c. Aktywacja silnika TTS w kodzie
|
|
|
|
Po zainstalowaniu wtyczki odkomentuj bloki oznaczone `[SHERPA]` w `TtsManager.cs`:
|
|
- `using SherpaOnnx;` (lub odpowiednia przestrzeń nazw wtyczki)
|
|
- blok konfiguracji `OfflineTtsConfig` w `InitCoroutine`
|
|
- blok `_tts.Generate(...)` w `SpeakCoroutine`
|
|
|
|
**Uwaga na espeak-ng-data:** Weryfikuj, czy Twoja wtyczka kopiuje `espeak-ng-data`
|
|
automatycznie ze StreamingAssets. Jeśli nie — spakuj katalog jako `.zip` i rozpakowuj
|
|
w `TtsManager.EnsureEspeakData()`.
|
|
|
|
---
|
|
|
|
## 5. Scena — podpinanie skryptów
|
|
|
|
### 5a. Obiekty w hierarchii
|
|
|
|
```
|
|
Scene
|
|
├── OVRCameraRig ← z Meta XR SDK
|
|
│ └── CenterEyeAnchor
|
|
├── SessionManager ← pusty GameObject
|
|
│ ├── CommandBank.cs
|
|
│ ├── TtsManager.cs
|
|
│ └── SessionController.cs
|
|
└── Canvas (World Space) ← panel UI
|
|
├── LoadingPanel
|
|
│ └── TMP_Text "Ładowanie..."
|
|
└── SessionPanel
|
|
├── TMP_Text "CommandText" ← główny tekst polecenia
|
|
├── Button "Next" ← trigger "następne"
|
|
└── LevelButtons
|
|
├── Button "L1"
|
|
├── Button "L2"
|
|
└── Button "L3"
|
|
```
|
|
|
|
### 5b. Inspector — SessionController
|
|
|
|
| Pole | Przypisz |
|
|
|---|---|
|
|
| Command Bank | GameObject SessionManager → CommandBank |
|
|
| Tts Manager | GameObject SessionManager → TtsManager |
|
|
| Command Text | TMP_Text CommandText |
|
|
| Loading Panel | GameObject LoadingPanel |
|
|
| Session Panel | GameObject SessionPanel |
|
|
| Next Button | Button Next |
|
|
| Start Level | 1 |
|
|
|
|
### 5c. Przyciski poziomu — OnClick
|
|
|
|
Każdy przycisk L1/L2/L3:
|
|
- Cel: SessionManager → SessionController
|
|
- Funkcja: `SetLevel(1)` / `SetLevel(2)` / `SetLevel(3)`
|
|
|
|
### 5d. TMP_Text — czcionka z polskimi znakami
|
|
|
|
Domyślna czcionka TMP może nie zawierać wszystkich polskich znaków. Aby to naprawić:
|
|
1. Pobierz czcionkę z polskim zestawem (np. Noto Sans Regular).
|
|
2. Utwórz **TMP Font Asset** (**Window → TextMeshPro → Font Asset Creator**),
|
|
zaznaczając znaki Latin Extended-A i Latin Supplement.
|
|
3. Przypisz nowy Font Asset do komponentu TMP_Text.
|
|
|
|
---
|
|
|
|
## 6. Build i sideload na Quest 3
|
|
|
|
```bash
|
|
# W Unity Editor:
|
|
# File → Build Settings → Android → Switch Platform
|
|
# Player Settings → Package Name: com.twojanazwa.ipinvr
|
|
# File → Build And Run (upewnij się, że Quest 3 podłączony przez USB + tryb dev)
|
|
```
|
|
|
|
Lub zbuduj APK i sideloaduj ręcznie:
|
|
```bash
|
|
adb install -r ipin-vr.apk
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Pomiar wydajności (cel PoC-1)
|
|
|
|
Po uruchomieniu na Queście zbierz metryki wg §7 z `docs/ONDEVICE.md`:
|
|
- **OVR Metrics Tool** (sideload z Meta) — FPS, CPU/GPU load, RAM
|
|
- **adb logcat** — `lowmemorykiller`, błędy sherpa-onnx
|
|
- **Perfetto** — latencja TTS od wywołania `Speak()` do pierwszego dźwięku
|
|
|
|
Metryki docelowe: PSS < 5,75 GiB, FPS stable 72/90, latencja TTS < 1 s.
|
|
|
|
---
|
|
|
|
## 8. Sanity check bez Unity (zalecane najpierw)
|
|
|
|
Zanim zaczniesz budować projekt, przetestuj głos na telefonie z Androidem:
|
|
1. Pobierz oficjalne APK TTS ze strony sherpa-onnx.
|
|
2. Sideloaduj i sprawdź jakość polskiego głosu `gosia-medium`.
|
|
3. Dopiero potem wchodź w pełny projekt Unity.
|