Skip to content

VRMA generator: lookAt sweep .vrma files fail UniVRM load (TransferOwnership null reference) #8

Description

@arkavo-com

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

  1. 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.
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions