feat: add rigged+animated Miku player model with auto-rig pipeline

- Add miku_rigged_animated.glb (3.27MB) with 18-bone skeleton and 6 animations
  (Idle, Walk, Run, Jump, Crouch, Death) via Blender auto-rig script
- Add tools/rig_and_animate.py: reusable Blender script for rigging any humanoid
  mesh with Mixamo-compatible bone naming
- Update SkinnedPlayerModel: scale_factor, first-person mode, animation state
  matching (Idle/Walk/Run/Jump/Crouch/Death)
- Update level_runtime.gd: use skinned model for local player, procedural
  humanoid for remote players
- Update skin_manager.gd and test_level_builder.gd to use animated model
- Fix Godot 4.2.1 'is not Type' syntax in 5 weapon files
- Add editor/import_miku_to_tscn.gd for editor-based GLB import
This commit is contained in:
2026-06-23 00:19:52 -04:00
parent f7cd3571fd
commit 0672bebe7b
13 changed files with 546 additions and 52 deletions
+17 -7
View File
@@ -141,13 +141,23 @@ func _spawn_player(pid: int) -> CharacterBody3D:
if mover_script:
player.set_script(mover_script)
# Humanoid Model for Player (Shadows only locally, visible to others)
var humanoid = load("res://characters/humanoid_model.gd").new()
humanoid.name = "HumanoidModel"
humanoid.color = Color(0.2, 0.4, 0.8) # Blueish for player
humanoid.shadows_only = (pid == multiplayer.get_unique_id())
humanoid.position = Vector3(0, -0.9, 0) # Offset from center to feet
player.add_child(humanoid)
# Visual Model for Player
var is_local = (pid == multiplayer.get_unique_id())
if is_local:
# Local player: use skinned Miku model with animations
var skinned = load("res://characters/skinned_player_model.gd").new()
skinned.name = "SkinnedModel"
skinned.model_path = "res://assets/characters/skins/miku_rigged_animated.glb"
skinned.first_person_mode = true # Hide body in FPS view, show only arms
player.add_child(skinned)
else:
# Remote players: use procedural humanoid
var humanoid = load("res://characters/humanoid_model.gd").new()
humanoid.name = "HumanoidModel"
humanoid.color = Color(0.2, 0.4, 0.8)
humanoid.shadows_only = false
humanoid.position = Vector3(0, -0.9, 0)
player.add_child(humanoid)
# Movement State Machine
var sm := Node.new()