A self-contained skeleton asset for animating characters and articulated objects.
A `SkeletonResource` encapsulates a skeleton's joint hierarchy together with optional
inverse-kinematics resources and blend masks in a single value. Use a skeleton resource
to define the joint structure of a character, then share it with animation-related APIs
such as retargeting configurations, IK rigs, and animation graphs.
You create a skeleton resource by providing a name and the root of a joint hierarchy.
A skeleton resource is immutable once created — the same instance is
safe to reuse anywhere in your app, including from background threads, without copying.
### Build a skeleton from a joint hierarchy
Build a skeleton's joint hierarchy using the ``Joint`` type and the ``JointBuilder`` result
builder. Each joint has a name and a rest-pose transform relative to its parent; nesting
joints inside the trailing closure declares parent-child relationships. Joint names must
be unique among siblings — the initializer throws an error if any children of the same
parent share a name.
```swift
typealias Joint = SkeletonResource.Joint
let skeleton = try SkeletonResource(
named: "Character",
rootJoint: try Joint("root") {
try Joint("spine", restPoseTransform: Transform(translation: [0, 0.1, 0])) {
try Joint("shoulder", restPoseTransform: Transform(translation: [0, 0.15, 0])) {
try Joint("upperArm", restPoseTransform: Transform(translation: [0, -0.3, 0])) {
try Joint("forearm", restPoseTransform: Transform(translation: [0, -0.3, 0])) {
try Joint("hand", restPoseTransform: Transform(translation: [0, -0.2, 0]))
}
}
}
}
}
)
```
### Add blend masks and inverse-kinematics resources
Blend masks let you control which joints an animation affects. Inverse-kinematics (IK)
resources let the runtime solve joint poses that meet positional or orientational targets —
for example, making a hand reach a point in space rather than following only pre-baked
motion. Bundle either or both into an ``AnimationEvaluation`` value and supply it when
you create the skeleton; that data then stays fixed for the lifetime of the resource.
Both lists default to empty if you don't need them.
Build a blend mask by listing per-joint weights between `0.0` (no animation) and
`1.0` (full animation). Joints you don't list keep the default `1.0`, so one entry
is often enough to silence a whole body region:
```swift
let blendMasks: [SkeletonResource.BlendMask] = [
.init(name: "armOnly", jointWeights: ["shoulder": 0.0]),
.init(name: "handOnly", jointWeights: ["shoulder": 0.0, "upperArm": 0.0, "forearm": 0.0])
]
```
Build an IK rig from the same joint hierarchy with ``IKRig/init(named:rootJoint:)``,
configure the constraints you need, then wrap the rig in an ``IKResource``. A skeleton
can carry more than one IK resource — for example, one configured for look-at
constraints and another for positional constraints — by passing each in the
`ikResources` array:
```swift
var rig = try IKRig(named: "armRig", rootJoint: rootJoint)
rig.constraints = [
.parent(named: "Hand_Task", on: "hand",
positionWeight: [50, 50, 50],
orientationWeight: [60, 60, 60])
]
let ikResource = try IKResource(rig: rig)
```
Finally, pass both into the skeleton when you create it:
```swift
let skeleton = try SkeletonResource(
named: "armSkeleton",
rootJoint: rootJoint,
animationEvaluation: .init(ikResources: [ikResource], blendMasks: blendMasks)
)
```
### Extract a skeleton from a loaded model
To pull a skeleton out of a USD-loaded model for use with the animation APIs, convert
the model's ``MeshResource/Skeleton`` with ``init(from:)``.
```swift
let entity = try await Entity.load(named: "Character")
let modelEntity = entity as! ModelEntity
if let meshSkeleton = modelEntity.model?.mesh.contents.skeletons.first {
let skeleton = try SkeletonResource(from: meshSkeleton)
}
```
### Use with retargeting
Pair a source and target `SkeletonResource` to build a retargeting configuration that
remaps animations across characters with different joint names or proportions, then
process source animations through it. See ``RetargetingConfiguration`` for the full
flow and the available matching strategies.
```swift
let config = try RetargetingConfiguration.automatchBiped(sourceSkeleton, to: targetSkeleton)
let retargeted = try sourceAnimation.processAndCreateAnimation(retargeting: config)
```
## Related Types
- ``Joint`` — a single joint in the skeleton hierarchy.
- ``AnimationEvaluation`` — bundle of IK resources and blend masks baked into the resource.
- ``BlendMask`` — selective per-joint weighting for layered animation control.
Members (4)
get · iOS 27.0+
animationEvaluation
TypeScript
get animationEvaluation(): SkeletonResource_AnimationEvaluation
Swift declaration
final let animationEvaluation: SkeletonResource.AnimationEvaluation
Animation-evaluation data baked into this resource at construction time.
Fixed at construction and immutable for the lifetime of the resource — every reader
observes the same value the initializer received.
Creates a skeleton resource with the specified name, joint hierarchy, and animation-evaluation data.
- Parameters:
- name: A unique identifier for the skeleton, used by the animation runtime to link
animation clips and retargeting configurations to this skeleton.
- rootJoint: The root joint of the skeleton hierarchy.
- animationEvaluation: Additional animation-related skeletal data to bake into the resource. Defaults to empty.
- Throws: If the joint hierarchy contains invalid data, or if the underlying resource cannot be created.
get · iOS 27.0+
rootJoint
TypeScript
get rootJoint(): SkeletonResource_Joint
Swift declaration
final var rootJoint: SkeletonResource.Joint { get }
The root joint of the skeleton hierarchy.
- Note: Each access walks the resource and rebuilds the entire
`Joint` tree. Bind the value to a `let` once when iterating or recursing over
the hierarchy rather than re-reading the property in a loop.