Avatar customization: skin tone, head swap, and hair now actually apply
checkpoint / checkpoint (push) Successful in 1m45s

Three dead controls on the customization screen:

- Skin tone slider did nothing: neither the visualizer nor AvatarSystem
  ever read loadout.skin_tone. Added AvatarLoader.apply_skin_tone() -- it
  retints the base body's skin surfaces (matched by the placeholder skin
  albedo, i.e. head + arms) -- and both build paths call it. Slider now
  maps across a deep-to-pale skin range.

- "Cyber Head" did nothing: its catalog entry was type "body_part", which
  load_attachment() rejects, and the placeholder body is one mesh so there
  was nothing to hide either. Retyped it as an attachment -> it mounts on
  the Head bone as a cyber visor.

- Mohawk / ponytail sat inside the head: the Head and HeadTop bones were
  well below the visual head (bone at 1.58, head crown at ~2.03). Moved
  Head to the head's centre and HeadTop just above the crown (mesh is
  rigidly bound, so it doesn't move), and retuned the hair/visor/glasses
  meshes and offsets to match.

Verified: avatar smoke 14/14 (source + pack), fresh-clone, 2p multiplayer,
and drove the real customization screen in rendered screenshots (equip
head+mohawk+mid skin, then ponytail+glasses+pale skin).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
This commit is contained in:
2026-09-06 16:10:46 +00:00
parent 181ba6ae02
commit 43a3b888da
11 changed files with 60 additions and 21 deletions
+2
View File
@@ -82,6 +82,8 @@ func load_loadout(loadout, root_node: Node3D = null) -> void:
if value is String and not (value as String).is_empty():
_loader.set_base_mesh_visible(slot_id, false)
_loader.apply_skin_tone(loadout.skin_tone)
build_complete.emit()