feat: implement modular character skinning system with procedural and imported model support

This commit is contained in:
DottsGit
2026-06-11 23:05:36 -04:00
parent 3bdf8f413b
commit 523fcc5226
14 changed files with 587 additions and 15 deletions
+43 -1
View File
@@ -75,8 +75,38 @@ var synced_loadout_p2: String = ""
var synced_loadout_sp: String = ""
var synced_loadout_melee: String = ""
var synced_loadout_ready: bool = false
@export var synced_skin_id: String = "default":
set(value):
var old = synced_skin_id
synced_skin_id = value
if old != value and is_node_ready():
_update_skin_visuals()
func _update_skin_visuals() -> void:
var sm = get_node_or_null("/root/SkinManager")
if not sm: return
var skin = sm.get_skin(synced_skin_id)
var humanoid = get_node_or_null("HumanoidModel")
if humanoid and humanoid.has_method("apply_skin"):
humanoid.apply_skin(skin)
var wman = get_node_or_null("HeadPivot/Camera3D/WeaponManager")
if wman and wman.has_method("refresh_arm_colors"):
wman.refresh_arm_colors()
func _ready() -> void:
# Set skin ID from SkinManager on authority
if is_multiplayer_authority():
var sm_node = get_node_or_null("/root/SkinManager")
if sm_node:
synced_skin_id = sm_node.selected_skin_id
if not is_node_ready():
await ready
_update_skin_visuals()
var sm := _ensure_machine()
if sm:
sm.player = self
@@ -783,7 +813,14 @@ func _on_movement_event(ev: String, data: Dictionary) -> void:
elif ev == "grapple_latch":
grapple_latch_player.play()
var _last_synced_skin_id: String = ""
func _process(delta: float) -> void:
if synced_skin_id != _last_synced_skin_id:
_last_synced_skin_id = synced_skin_id
if is_node_ready():
_update_skin_visuals()
# Remote players: apply synced movement state to their HumanoidModel
if not is_multiplayer_authority():
if synced_loadout_ready and not has_meta("remote_weapons_built"):
@@ -984,7 +1021,12 @@ func die(impulse: Vector3 = Vector3.ZERO) -> void:
ragdoll_instance = ragdoll
get_tree().current_scene.add_child(ragdoll)
ragdoll.global_transform = global_transform
ragdoll.build_ragdoll(Color(0.2, 0.4, 0.8)) # Blueish player color
# Use skin for ragdoll appearance
var skin_mgr = get_node_or_null("/root/SkinManager")
if skin_mgr:
ragdoll.build_ragdoll(skin_mgr.get_skin(synced_skin_id))
else:
ragdoll.build_ragdoll(Color(0.2, 0.4, 0.8))
# Wait a frame for physics to initialize then apply velocity
get_tree().create_timer(0.01).timeout.connect(_apply_ragdoll_velocity.bind(ragdoll, velocity, impulse))