feat: implement modular character skinning system with procedural and imported model support
This commit is contained in:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user