Symptom
All 10 lookAt sweep .vrma files (vrma_lookat_*_bone and vrma_lookat_*_expr) emitted by cargo run -p vrm-asset-generator -- emit-vrma-lookat-sweep fail UniVRM v0.131.0's VrmAnimationImporter.LoadAsync with:
```
System.NullReferenceException: Object reference not set to an instance of an object
at UniVRM10.VrmAnimationImporter.TransferOwnership (UniGLTF.TakeResponsibilityForDestroyObjectFunc take)
in com.vrmc.vrm@.../Runtime/IO/VrmAnimationImporter.cs:303
at UniGLTF.RuntimeGltfInstance.AttachTo (UnityEngine.GameObject go, UniGLTF.ImporterContext context)
in com.vrmc.gltf@.../Runtime/UniGLTF/RuntimeGltfInstance.cs:108
```
three-vrm reads the same .vrma files and produces correct pose dumps (scripts/vrma-pose-consensus.py shows three-vrm: 37/37; UniVRM: 15/37 — all 10 lookAt failures).
Likely cause
Our `vrma_emit::add_look_at_channel` (commit `c8c2a8b`) emits a .vrma with:
```json
{
"extensions": {
"VRMC_vrm_animation": {
"specVersion": "1.0",
"lookAt": { "node": 0, "offsetFromHeadBone": [0, 0.06, 0] }
}
}
}
```
No humanoid.humanBones block — the .vrma is lookAt-only. `TransferOwnership` at line 303 of VrmAnimationImporter is called AFTER the importer parses humanoid + expression + lookAt blocks. It probably dereferences a humanoid-related field that wasn't initialized when humanoid is absent.
Fix candidates
- Always emit at least the 15 required VRMA humanoid bones in `humanBones` even on lookAt-only .vrma. The existing `register_all_humanoid_bones` helper (added in commit `35db5c6` for the canonical .vrm rig) would work but needs adaptation since lookAt .vrma uses a different node hierarchy.
- Read the TransferOwnership source at line 303 to confirm exactly which field is null; fix the specific shortfall.
Reproduction
```bash
cargo run --release -p vrm-asset-generator -- emit-vrma-lookat-sweep --output-dir /tmp/lookat
mkdir -p /tmp/lookat-stage
cp /tmp/lookat/vrma_lookat_yaw_pos60_bone.* /tmp/lookat-stage/
target/release/vrm-runner execute-test-batch
--plans "$(pwd)/lookat-stage"
--adapter-bin "$(pwd)/adapters/univrm/launcher.sh"
--output-dir "$(pwd)/lookat-out"
--renderer-name univrm
```
Expected: error message above in `lookat-out/results.ndjson`.
Why three-vrm tolerates it
three-vrm's createVRMAnimationClip handles missing humanoid section gracefully — empty Map for humanoidTracks rather than null deref.
Acceptance
10/10 lookAt plans load through UniVRM batch.
Symptom
All 10 lookAt sweep .vrma files (
vrma_lookat_*_boneandvrma_lookat_*_expr) emitted bycargo run -p vrm-asset-generator -- emit-vrma-lookat-sweepfail UniVRM v0.131.0'sVrmAnimationImporter.LoadAsyncwith:```
System.NullReferenceException: Object reference not set to an instance of an object
at UniVRM10.VrmAnimationImporter.TransferOwnership (UniGLTF.TakeResponsibilityForDestroyObjectFunc take)
in com.vrmc.vrm@.../Runtime/IO/VrmAnimationImporter.cs:303
at UniGLTF.RuntimeGltfInstance.AttachTo (UnityEngine.GameObject go, UniGLTF.ImporterContext context)
in com.vrmc.gltf@.../Runtime/UniGLTF/RuntimeGltfInstance.cs:108
```
three-vrm reads the same .vrma files and produces correct pose dumps (
scripts/vrma-pose-consensus.pyshows three-vrm: 37/37; UniVRM: 15/37 — all 10 lookAt failures).Likely cause
Our `vrma_emit::add_look_at_channel` (commit `c8c2a8b`) emits a .vrma with:
```json
{
"extensions": {
"VRMC_vrm_animation": {
"specVersion": "1.0",
"lookAt": { "node": 0, "offsetFromHeadBone": [0, 0.06, 0] }
}
}
}
```
No
humanoid.humanBonesblock — the .vrma is lookAt-only. `TransferOwnership` at line 303 of VrmAnimationImporter is called AFTER the importer parses humanoid + expression + lookAt blocks. It probably dereferences a humanoid-related field that wasn't initialized when humanoid is absent.Fix candidates
Reproduction
```bash
cargo run --release -p vrm-asset-generator -- emit-vrma-lookat-sweep --output-dir /tmp/lookat
mkdir -p /tmp/lookat-stage
cp /tmp/lookat/vrma_lookat_yaw_pos60_bone.* /tmp/lookat-stage/
target/release/vrm-runner execute-test-batch
--plans "$(pwd)/lookat-stage"
--adapter-bin "$(pwd)/adapters/univrm/launcher.sh"
--output-dir "$(pwd)/lookat-out"
--renderer-name univrm
```
Expected: error message above in `lookat-out/results.ndjson`.
Why three-vrm tolerates it
three-vrm's createVRMAnimationClip handles missing humanoid section gracefully — empty Map for humanoidTracks rather than null deref.
Acceptance
10/10 lookAt plans load through UniVRM batch.