MasterNin ECSAnimator
On this page

Crossbow IK: aim at a changing target height

Updated October 7, 2026. This preview adds programmatic pose processing to the skeletal ECS animation workflow. The crossbow example adjusts both arms and the weapon's pitch during Attack without needing a separate animation for each target height.

Dependency baseline

The candidate manifest specifies Burst 1.8.21. Check the resolved version in Package Manager and restart the Editor after dependency changes. Upgrading Burst alone has not been established as a fix for the intermittent Unity 2022.3.1f1 / Direct3D 11 native crash. Disabling IK or diagnostic rays is an isolation experiment, not a qualified release fix. Final archive installation qualification remains pending.

Try the included comparison

  1. Import Demos from ECSAnimator's Samples in Package Manager.
  2. Run Tools > ECSAnimator > Demos > Use Demo Render Settings.
  3. Open 14_TwoBoneIK/Scenes/14_TwoBoneIK.unity and enter Play.
  4. Blue plays the original animation. Red adds two arm chains and foregrip following. Leave Auto attack enabled and watch the target change height.
  5. Disable Auto target, then change Target elevation to compare low, level and high targets. Toggle Enable IK or change IK strength to compare against the original pose.
  6. Enable Hold aiming pose to hold both characters at normalized Attack time 0.25. This is the aiming instant used in the corrected promotional images and video. Release the toggle to resume playback.

The supplied scene and corrected recording use a red target. The shot ray originates at the central bolt rail's launch point and follows its actual direction after skinning. Calibration uses the front and rear rail edges, not the outer bow limb or mesh +Z. The muzzle and support-hand markers were recalibrated from the Attack aiming pose, and the runtime resource was rebuilt. Refresh existing imported Samples after preserving local changes.

Muzzle 3D error measures the complete angle to the target, including lateral error. The line remains a straight shot ray; it is not forced to connect to the red dot. At limited angles, partial strength, disabled IK or sideways targets, the ray can miss. The corrected held-pose recording uses the supplied hold toggle and camera/caption presentation settings; it is not a separate animation.

What changes, and what stays animated

Target height and forward distance determine vertical aim in the character-root YZ plane. Pitch rotates about the horizontal root X axis. Sideways target movement does not turn the character. Body heading, waist and legs retain the source animation; this sample does not bend the waist to aim.

The default pitch limit is +/-45 degrees. Targets beyond it demonstrate clamping: the weapon holds its permitted angle and may not point exactly at the target. The right arm positions the weapon, then the left hand follows the solved foregrip. Limb segment lengths remain fixed; unreachable hand targets are clamped without stretching.

Correction fades in with Attack and out after it. At zero strength the original animation is restored. At partial strength, aim and hand placement are deliberately only partially corrected. Attack Speed defaults to 0.35 to make the short source shot easy to observe; it is an actual state-speed parameter.

Integrate with your gameplay

Enable Require Pose Processing during conversion to produce LocalResolve data. Check prepared.SupportsPoseProcessing, resolve the current character's exported bone indices, and supply root-space targets, hints, rotations and weights from your gameplay.

The sample registers a static Burst CharacterPoseProcessor and unmanaged per-character data. Its CrossbowPoseProcessor solves the right arm, reads the corrected hand/foregrip, then solves the left arm. It runs after Animator blending and before skinning and attachment output. Other characters can omit the processor entirely.

See the sample README and source for controls and calibrated weapon markers, and the pose-processing API for ownership, scheduling, failure behavior and a minimal callback. The sample's stable Resources key still contains 21_TwoBoneIK; the visible scene is now numbered 14.

Support boundaries

The preview package retains version 0.1.0-preview.1; use the delivery date and archive hash to distinguish it from earlier builds. Existing imported Samples are project-owned copies and must be refreshed separately after preserving local changes.