Fix inverted entity name guard in AnimComponentBinder - #9187
Conversation
The guard in _getEntityFromHierarchy negated the entity name before comparing it to the path root, so it never fired. Fix the comparison and restore null handling in resolve() so unresolved entity paths leave curves unbound instead of misbinding or throwing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Build size reportThis PR changes the size of the minified bundles.
|
mvaligursky
left a comment
There was a problem hiding this comment.
🤖 Automated PR review — posted on my behalf by Claude Code (Opus 4.8). Not a human review. The points below are suggestions to weigh as possible improvements, not changes that necessarily need to be addressed.
The fix and the restored null handling are correct (I verified the evaluator contract claim: a null resolve() leaves the curve unbound, matching the unresolvable-component path), and the multi-element cases are a strict improvement — those either mis-bound into siblings or threw. Two points on the newly-strict behavior, both about the same risk:
-
Single-element paths are a working-content regression, and arguably shouldn't be gated at all. With the old code, a one-element
entityPathbound the anim component's own entity regardless of the name — so property animations kept working after the entity was renamed, and clips were reusable across differently-named entities. For a one-element path the target is unambiguous (there's nothing to resolve — it can only mean the component's own entity), so the name check there adds strictness without disambiguating anything, and silently breaks that previously-working pattern. Consider keeping the one-element case lenient (returncurrEntitywithout the name check, optionally with a debug warning on mismatch) and applying the guard only to multi-element paths, where the root name actually anchors_parent.findByPathand where the real mis-bind/crash bugs lived. -
The new rejections are silent. When the guard fires, curves just stop animating with no diagnostic — for anyone whose content depended on the old leniency, that's a hard thing to trace. A debug-build
Debug.warnat the guard (naming the track's root vs the entity's name) would make both the new rejections and legacy-content migration self-explanatory, and matches how other unresolvable-binding cases in the anim system could be surfaced.
The regression tests are well-constructed and cover both conventions and all three failure modes.
Address review feedback: a one element entity path can only target the anim component's own entity, so binding it regardless of the authored root name preserves content that renamed the entity or reuses clips across differently named entities. Multi element paths still require the root name to match, and now emit a debug warning when rejected instead of silently unbinding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Adopted both review suggestions in d0dbc73, with one refinement to the first:
One test flipped to lock in the lenient single element behavior; the PR description now also calls out the one deliberate break (intentional sibling-subtree animation) explicitly. 🤖 Generated with Claude Code |
Description
AnimComponentBinder._getEntityFromHierarchywas written asif (!this.animComponent.entity.name === entityHierarchy[0]), which coerces the name to a boolean before comparing it to a string, so the guard has never fired since its introduction in #2007. Anim tracks targeting entity or component properties were bound without ever validating that the path is rooted at the anim component's entity.Changes
Debug.warnOncenames the authored path and the entity, instead of resolving throughcurrEntity._parent.findByPath(...)into a sibling entity's subtree or throwing.resolve()after both_getEntityFromHierarchycall sites (present in the original implementation, dropped in the [Animation] Binding updates and bug fixes #2772 refactor). An unresolved path — including a matching root with a missing descendant — now returns null (curve left unbound, per the AnimEvaluator contract) instead of throwing.Behavioral consequences
graph) tracks resolve throughDefaultAnimBinder.findNodeand its fallback chain, which this change does not touch.Checklist
🤖 Generated with Claude Code