You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 350b75d
Browse filesBrowse the repository at this point in the historyBrowse files
fix(snippets): bind the action slot on the 4.5 LTS channelbag path (#406)
On 4.5 LTS the snippet wrote keys through legacy action.fcurves.new() on a
slotless Action. That creates a "Legacy Slot" but never assigns it, so
animation_data.action_slot stays None and the object never animates; no
error is raised. Measured on 4.5.11: z stayed 0.0 at frame 24 instead of 2.0.
The snippet now binds the slot on both versions and builds the 4.5
layer/strip/channelbag path with strip.channelbag(slot, ensure=True),
mirroring the skill's get_channelbag_for_slot helper. The skill's legacy
section now binds the slot explicitly and says why, and its table and
cross-version intro stop recommending bare action.fcurves.
Closes#385
Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: skills/slotted-actions-animation/SKILL.md
+10-5Lines changed: 10 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,7 +41,7 @@ On 5.0+, code that walks `action.fcurves` directly raises `AttributeError` becau
41
41
42
42
`bpy_extras.anim_utils.action_ensure_channelbag_for_slot(action, slot)` is **new in Blender 5.0**. It ensures the Action has a Layer, a Strip in that Layer, and a Channelbag for the given Slot, then returns the Channelbag. It does **not** exist on 4.4 / 4.5 LTS — there is no auto-detecting shim, and importing-and-calling it on 4.5 raises `AttributeError`.
43
43
44
-
On 4.4 / 4.5 LTS, ensure the channelbag yourself with `strip.channelbag(slot, ensure=True)` (the slotted model is present there), or just use the still-present legacy `action.fcurves`. So a genuinely cross-version helper must branch on `bpy.app.version`:
44
+
On 4.4 / 4.5 LTS, ensure the channelbag yourself with `strip.channelbag(slot, ensure=True)` (the slotted model is present there). The still-present legacy `action.fcurves` is a trap on a fresh Action: it creates a slot but does not bind it (see the legacy section below). So a genuinely cross-version helper must branch on `bpy.app.version`:
45
45
46
46
Import path (5.0+) verified against the Blender 5.1 API reference: `bpy_extras.anim_utils.action_ensure_channelbag_for_slot(action, slot)`. See [`bpy_extras.anim_utils`](https://docs.blender.org/api/current/bpy_extras.anim_utils.html).
47
47
@@ -156,24 +156,29 @@ Notes:
156
156
157
157
## The legacy `action.fcurves` path (4.4 / 4.5 LTS only)
158
158
159
-
On 4.4 and 4.5 LTS the legacy flat API is still presentand is the simplest path if you do not need to target 5.x:
159
+
On 4.4 and 4.5 LTS the legacy flat API is still present, but on a fresh Action it does **not** bind a slot. `action.fcurves.new(...)` creates a slot named `Legacy Slot`and leaves `obj.animation_data.action_slot` as `None`, so the keys exist and the object never animates. Bind the slot yourself after the first legacy write:
# The legacy write created the slot but did not assign it.
176
+
obj.animation_data.action_slot = action.slots[0]
172
177
fcurve.keyframe_points.insert(1, 0.0)
173
178
fcurve.keyframe_points.insert(24, 5.0)
174
179
```
175
180
176
-
This works on 4.4 / 4.5 LTS, but on **5.0+** the `action.fcurves` attribute was removed entirely, so `action.fcurves.new(...)` raises `AttributeError`. For 5.x, go through the channelbag (`get_channelbag_for_slot` above).
181
+
Measured on 4.5.11 LTS: without the `action_slot` line, `frame_set(24)` leaves the object at its rest value. Prefer the channelbag path (`get_channelbag_for_slot` above), which binds the slot before writing on every version. On **5.0+** the `action.fcurves` attribute was removed entirely, so `action.fcurves.new(...)` raises `AttributeError`.
177
182
178
183
## Detecting the version boundaries
179
184
@@ -204,7 +209,7 @@ The slotted data model (and `action.slots`) is meaningful on 4.4 and 4.5 too, so
204
209
# Missing: setting obj.animation_data.action_slot
205
210
```
206
211
207
-
Without a slot binding, the Action has no idea which datablock it drives. Symptom: animation plays back as if it isn't there.
212
+
Without a slot binding, the Action has no idea which datablock it drives. Symptom: animation plays back as if it isn't there. On 4.5 LTS the legacy `action.fcurves.new(...)` path hits this silently: it creates a slot but never assigns it.
208
213
209
214
3.**Hardcoding the import path** to where it was in some older 5.x. Verify against current docs:
| Insert a single keyframe |`obj.keyframe_insert("location", frame=1)`| Same | High-level API works on both |
223
-
| Get the F-curves for an Action+Slot |`strip.channelbag(slot, ensure=True)`, or legacy `action.fcurves`|`action_ensure_channelbag_for_slot(action, slot)`|`get_channelbag_for_slot(action, slot)` (branches on version) |
228
+
| Get the F-curves for an Action+Slot |`strip.channelbag(slot, ensure=True)` (legacy `action.fcurves` only with an explicit `action_slot` bind)|`action_ensure_channelbag_for_slot(action, slot)`|`get_channelbag_for_slot(action, slot)` (branches on version) |
224
229
| Create an Action |`bpy.data.actions.new(...)`| Same | Same |
225
230
| Bind Action to ID |`obj.animation_data.action = action` + `action_slot`| Same |`action_slot` is settable on 4.4+; set both |
0 commit comments