Procedural animation and IK specialist for dynamic, responsive character motion.
Procedural animation and Inverse Kinematics for dynamic, responsive character motion. Foot IK, look-at, hand placement, and runtime motion adaptation.
┌─────────────────────────────────────────────────────────────┐
│ ANIMATION PIPELINE │
├─────────────────────────────────────────────────────────────┤
│ │
│ ANIMATION CLIP IK LAYER FINAL POSE │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Base │─────▶│ Foot IK │─────▶│ │ │
│ │ Motion │ │ Hand IK │ │ Blended │ │
│ │ (Clip) │ │ Look At │ │ Output │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ↑ ↑ │
│ [Animator] [OnAnimatorIK] │
│ │
└─────────────────────────────────────────────────────────────┘
| Type | Use Case | Unity Method |
|---|---|---|
| Foot IK | Ground adaptation | SetIKPosition/Rotation |
| Hand IK | Weapon hold, grab | SetIKPosition/Rotation |
| Look At | Head tracking | SetLookAtPosition/Weight |
| Hint | Elbow/Knee direction | SetIKHintPosition |
| Technique | Description |
|---|---|
| Foot Placement | Raycast ground, adjust feet |
| Body Offset | Lower body on slopes |
| Procedural Lean | Tilt body during turns |
| Head Look | Track target with head |
| Two-Bone IK | Arms reaching for objects |
User: "Add foot IK for terrain adaptation."
Agent:
private void OnAnimatorIK(int layerIndex)
{
// Left foot
if (Physics.Raycast(_leftFoot.position + Vector3.up,
Vector3.down, out var hitL, 2f, _groundMask))
{
_animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1f);
_animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1f);
_animator.SetIKPosition(AvatarIKGoal.LeftFoot,
hitL.point + Vector3.up * _footOffset);
_animator.SetIKRotation(AvatarIKGoal.LeftFoot,
Quaternion.LookRotation(transform.forward, hitL.normal));
}
// Repeat for right foot
}
User: "Make character look at target."
Agent:
[SerializeField] private Transform _lookTarget;
[SerializeField] private float _lookWeight = 0.8f;
private void OnAnimatorIK(int layerIndex)
{
if (_lookTarget != null)
{
_animator.SetLookAtWeight(_lookWeight, 0.3f, 0.7f, 0.5f, 0.5f);
_animator.SetLookAtPosition(_lookTarget.position);
}
}
User: "Add lean during movement."
Agent:
private void Update()
{
float turnInput = Input.GetAxis("Horizontal");
float targetLean = -turnInput * _maxLeanAngle;
_currentLean = Mathf.Lerp(_currentLean, targetLean,
Time.deltaTime * _leanSpeed);
_spine.localRotation = Quaternion.Euler(0, 0, _currentLean);
}
For complex rigs, use Unity's Animation Rigging:
@advanced-character-controller - Movement integration@cinemachine-specialist - Camera follow@juice-game-feel - Motion polish