Skip to content
Bit Quirky Behavior Trees and
State Machines

Search documentation

All topics and APIs

Close returns focus to Search.

What are you looking for?

Try a common topic or enter a complete API identifier.

Browse the reference instead

Esc closes · Tab reaches results · Enter opens the focused link

v0.6.0
Menu

AOT and IL2CPP

What the importer generates for your bindings, where it gets wired, and what to re-run after you change a signature.

Bindings are compiled C#, generated when the graph is imported. There is no reflection on the tick path and no linker list for you to maintain.

A reflective binding layer looks fine in the Editor and then meets IL2CPP, where the member it wanted to invoke was stripped, or the call costs more than the behavior it drives. Shipping to consoles and mobile with per-tick reflection is how a graph tool becomes the thing you profile out.

So the importer writes the call sites as source. Your bindings turn into ordinary compiled methods in your own assembly, and the runtime calls them like any other code.

  • The first time you press Play on a graph with bindings and the agent asks for a provider.
  • After you rename a bound member or change its parameters.
  • Before a player build, especially an IL2CPP one.
  1. Author the bindings, then press Save (Cmd/Ctrl+S). Autosave writes the graph file only; Save imports it and generates a provider for that graph into your project.

  2. Wait for Unity to compile. Generation and compilation are two steps, and validation is honest about which one is pending.

  3. On a GameObject agent, assign the generated component to Member Provider Component beside the graph.

  4. On an entity graph, pass the generated binding set and its scheduler together when you register the graph. There is no inspector field for that path.

  5. Read Validation before building. It compares the graph file, the manifest, the generated code, the compiled result, and the preservation metadata.

Both paths write into a folder per graph, named by the graph asset’s GUID, under your project’s generated member folder. Each folder holds the generated code and a link.xml that preserves every declaring type your bindings touch with preserve="all", so an IL2CPP player cannot strip a type that is only ever reached through a generated call.

GameObject path. A [Preserve] sealed MonoBehaviour called BehaviorMemberProvider_<graph guid>, implementing the provider interface and its diagnostics interface, carrying a Fingerprint constant for the binding set it was generated from. It holds one method per accessor: the exact call, the exact property or field access, the exact event subscribe and unsubscribe. It never resolves a member by reflection, never keeps global state, and never falls back to a dynamic invocation. A non-public declaration you opted into with [BehaviorMember] resolves one strongly typed delegate while the provider initializes, so even that case is not a per-tick lookup.

Entity path. A [BurstCompile] static class holding the typed carrier struct the job uses, a scheduler, and a factory that builds the binding set. Its component and buffer handles are visible typed fields, which is what lets Unity’s job reflection register the graph job’s real access, and its access table records read-only or read-write intent per component.

You do not write or maintain either artifact, and you never hand-edit the linker file.

Press Save or reimport the graph file so the generated code is rewritten, then let Unity compile. That order matters: a player build validates what exists and never generates first-time output, which is why an unbuilt change fails the build instead of quietly shipping a stale call.

Validation names exactly what is wrong. A stale provider states the expected and the found fingerprint and asks you to regenerate. A missing entity binding set says the consumer assembly compiles none and asks for a reimport. Missing or stale linker metadata says so on its own. A leftover artifact from the other path, such as a GameObject provider still sitting beside an entity graph, is reported rather than ignored.

When it goes wrong

SymptomCheckFix
Entering Play Mode throws about a member provider.The agent runs a graph with bindings and the provider slot is empty.Assign the generated component to Member Provider Component.
The provider component does not exist yet.Generation happened, compilation has not.Wait for the compile to finish, then assign it.
Validation reports a stale fingerprint.Compare the expected and found values in the message.Reimport the graph file and let the assembly recompile.
A build fails on missing generated code.A build never generates for the first time.Reimport in the Editor, compile, then build.
A bound type is missing in an IL2CPP player.Confirm the generated linker metadata is present and current.Reimport the graph file so that metadata is rewritten.
Every call reports a failure after an upgrade.An unavailable provider keeps its type and refuses every invocation by design.Regenerate the provider so a real one replaces the placeholder.
Full-size image