3.2 KiB
Animator As Crab
A hard fork of Animator As Code where animator controllers are written in Rhai instead of C#.
A Rhai script is evaluated by a Rust library (libaac), which validates it and emits the whole
controller as JSON. A Unity Editor window deserializes that JSON and builds a real
AnimatorController through the original Animator As Code V1 library, which is left untouched.
script.rhai --> libaac (Rust) --JSON--> AacCrabWindow (Unity Editor) --> AnimatorController
Layout
| Path | Contents |
|---|---|
rust/ |
The Rhai DSL, graph model, validator, and the libaac cdylib. |
rust/examples/avatar.rhai |
The reference script, exercising every feature of the DSL. |
csharp/dev.doloro.animator-as-crab/ |
The Unity package: the untouched Animator As Code V1 library and the bridge in V1/Editor/Crab/. |
flake.nix |
Dev shell with the Rust toolchain, dotnet, mono, and jq. |
Building
nix develop
cargo test --manifest-path rust/Cargo.toml
cargo run --bin aac-dump -- rust/examples/avatar.rhai # print the generated JSON
nix build .#aac # libaac.so + aac-dump
Copy libaac.so (or libaac.dll, libaac.dylib) into the Unity project's Assets/Plugins folder,
and add csharp/dev.doloro.animator-as-crab to the project's packages.
Writing a script
let aac = AnimatorAsCode();
aac.system_name("MyAvatar");
aac.asset_key("AAC_");
let speed = aac.float_param("Speed", 0.0);
let ctrl = aac.new_controller();
let base = ctrl.layer("Base");
let idle = base.state("Idle", 0, 0);
let walk = base.state("Walk", 1, 0);
let walk_clip = aac.clip("walk_anim");
walk_clip.toggle("Body/Props", true);
walk.set_clip(walk_clip);
idle.transition_to(walk).when(speed > 0.1).no_exit_time().duration(0.25);
Conditions are written on the parameters themselves (speed > 0.1, is_sitting == true).
There is no && or || — Rhai's are short-circuit built-ins that cannot be overloaded — so
use when_all([speed < 0.05, is_sitting == false]).
See rust/examples/avatar.rhai for the full surface: parameters, clips, curves, blend trees,
sub-state machines, any-state transitions, and transition settings.
Generating
Open Tools > Animator As Crab and fill in the window:
- the path to the
.rhaiscript (it is watched, so saving the script regenerates the controller), - the
AnimatorControllerto generate into, - the animator root, the asset container, and the container mode,
- whether states should write defaults.
Nothing is defaulted silently, and the controller is rebuilt with Animator As Code's modification API: the controller is cleared, and the clips and blend trees of the same asset key are removed from the container before being recreated. Animator As Code's own C# API is untouched and still usable on the same controller.
Limitations
- The Unity side has not been run: there is no Unity project in this repository, so the bridge and the generator are verified by reading, not by executing.
- Blend trees can only nest a blend tree that was declared earlier in the script.
- The graph carries no avatar masks, layer weights, state behaviours, or parameter drivers yet.