"Why SetBoneTransform / SetIk silently do nothing"
- You call
SetBoneTransform/TryGetBoneTransformand nothing useful happens — or worse, tails wind through the floor / torso spazzes. SetIk/ClearIkcompile and run but hands/feet never reach the target.- No exception; silent failure or intermittent corruption.
Two different APIs, two different traps:
SetIk is AnimGraph-gated
SkinnedModelRenderer.SetIk does nothing on a direct-sequence rig. Engine XML docstring (Sandbox.Engine.xml):
Sets an IK parameter. This sets 3 variables that should be set in the ANIMGRAPH:
ik.{name}.enabled/position/rotation.
Working hand/foot IK needs a .vanmgrph with those params wired. If you play sequences directly (Sequence.Name = ..., no AnimGraph), SetIk / ClearIk are inert.
SetBoneTransform is unsound on clip-animated bones
The API exists (TryGetBoneTransform[Local], SetBoneTransform(in Bone, localTx) — verified against Sandbox.Engine.dll) but behaves inconsistently:
- Overrides persist on bones the active sequence does not key → reads return your own prior write → unbounded accumulation (e.g. tail through the floor).
- Overrides get stomped on bones the sequence does key → a delta-backout then corrupts the clean pose → torso spazz through shared skin weights.
Read-modify-write against live bone state cannot be made safe from component code on a sequence-driven rig.
There is a newer Procedural Bones path (GetBoneObject(i) → move the bone GameObject → ReadBonesFromGameObjects()), distinct from SetBoneTransform — but the bone must be flagged Procedural (model/AnimGraph authoring), and RMW against clip-keyed bones is still unsound.
Verdict for a sequence-only rig: no runtime hand IK without authoring an AnimGraph.
When hands must grab a moving world target on such a rig:
- Proxy props welded to the target in world space — small meshes parented to the character root (not a visual child that carries squash/flip). Cartoon-acceptable, zero rig work.
- Whole-visual motion — rotate/offset the visual GameObject; bake follow-through into clips.
- Commit to AnimGraph — additive layers, bone masks, real IK params (
renderer.Set("param", value)/Parameters.Set/SetLookDirection/UseAnimGraph). Citizen'sCitizenAnimationHelperis the reference caller pattern.
For ragdoll crumple, use ragdoll-scripted-rig-npc (ModelPhysics) — not per-bone C# posing.
For smooth clip switches only, use crossfade-without-animgraph — do not reach for SetBoneTransform.
Sequence playback owns the pose every frame for keyed bones; writing over that from gameplay code fights the animator. SetIk was never a free IK solver — it only feeds AnimGraph parameters. Proxy props sidestep the skeleton entirely: the grab is a separate scene object, so there is no bone write to corrupt or ignore.