Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit44fd9e59bd

README.md

Humanoid

Marker component for entities carrying a skeleton conforming to the standard humanoid bone layout (Synty / Unreal-Mannequin convention). Content reads a humanoid body's bones and attachment sockets through this component instead of re-walking the descendant tree, and seats items on those sockets with :attach.

Bone naming convention

Hips
  Spine_01 → Spine_02 → Spine_03 → Neck → Head
                                            └ Eyes, Eyebrows, Jaw
  UpperLeg_R / UpperLeg_L
    LowerLeg_R / LowerLeg_L
      Ankle_R / Ankle_L
        Ball_R / Ball_L → Toes_R / Toes_L
  Clavicle_R / Clavicle_L
    Shoulder_R / Shoulder_L
      Elbow_R / Elbow_L
        Hand_R / Hand_L
          IndexFinger_01..04 / Thumb_01..04 / Finger_01..04

Mixamo / Unity-Humanoid imports go through a bone-rename pass at import time (tracked separately).

Fields

FieldTypeNotes
heightnumberFoot-to-head height in T-pose, metres. Default 1.8.
eye_heightnumberFoot-to-eyes height, metres. Default 1.65.
bones{ [string]: entity }Computed; bone-name → entity-proxy map. Re-walks on read.
sockets{ [string]: entity }Computed; role (righthand, head, …) → the bone filling it on this body, through the body's RetargetProfile.

Methods

MethodReturnsNotes
:bone(name)entity | nilNil-safe single-bone lookup; same as self.bones[name].
:socket(point)entity | nilThe bone at a role, or at an exact bone name.
:attach(point, childId, opts?)entity | nilSeats childId on the socket bone at the socket's frame, moved by opts.position / opts.rotation / opts.scale. Position and scale are metres in the humanoid's own space, whatever bone units the rig was authored in; rotation is relative to the bone, as a quaternion { x, y, z, w } or Euler degrees { pitch, yaw, roll }. An option outside those three, or a value in none of those forms, raises with the item left as it was. Returns the socket bone.
:attachments(){ { id, point, position, rotation, scale } }Every item seated with attach, with the point and transform it was seated with. An avatar body swap re-seats each on the new body.

The sockets are slots of the Slot family: an Assembly on a humanoid lists each role socket as a slot of that kind (righthand, head, ...) and fills it with a part whose Part.fits names the role, seated the way :attach seats an item (guides { path: "topics/assemblies" }).

Usage

-- Read a specific bone
local h = entity(playerId).component.get("Humanoid")
local head = h.bones.Head                -- entity proxy
local handR = h:bone("Hand_R")           -- nil-safe lookup

-- Seat a hat 12 cm above the head, on any humanoid body
local hat = entity.spawn("hat")
h:attach("head", hat.id, { position = { 0, 0.12, 0 } })

-- Read height for camera mounting
local cam = entity.spawn("eye_cam", { parent = playerId })
cam.localPosition = { 0, h.eye_height, 0 }

Ragdolling a humanoid

animation.ragdoll(playerId) makes the body a ragdoll: bodies sized per body part, hinged knees and elbows, cones at the shoulders, hips and neck. A description names bones by the same roles as sockets (head, leftarm, rightleg, ...), so it fits every humanoid body. The physics guide's "Ragdolls" section (guides { path: "topics/physics" }) has the rest.

animation.ragdoll(playerId)                                   -- collapse
animation.ragdoll(playerId, { limp = { "rightarm" } })        -- one arm hangs, the rest animates
animation.ragdoll(playerId, false)                            -- back to the animation

Tag convention

Bundles carrying a humanoid skeleton tag themselves with both playerVisual AND humanoid in their .metadata. Tooling can filter to humanoid-conforming visuals via asset.list("bundle", nil, { fields = { tags = { "playerVisual", "humanoid" } } }).