feat: real two-hand rifle hold — armed animations finally read as a shooter
The clips were playing all along, but every locomotion state used unarmed jog arms while the gun floated at the hip, so nothing looked animated. - ShooterPoseModifier now REPLACES the arm chain with a direction-based FK rifle hold (low-ready at hip, shouldered on ADS) instead of nudging the unarmed clip additively; the wrist is solved so the muzzle points exactly along the aim line, gun kept upright (no-roll constraint). - Per-arm release logic: reload/throw/hit one-shots, dance, death, the slide ground-brace, wall-run reach and grapple free the authored clips. - Third-person weapon: fixed re-hide on weapon swap while in third person, scaled to character proportions, gripped along the hand. - Armed idle uses Idle (arms owned by the hold) instead of arms-crossed PistolIdle base. - FP viewmodel arms: character-styled sleeve + teal cuff + skin hand instead of the blue slabs. - debug/anim_capture.gd: front+side screenshots of every movement state, one-shot action and ADS for visual regression of the model pipeline. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5
parent
39af109893
commit
6c227b5538
+47
-40
@@ -273,47 +273,54 @@ func _set_layer_recursive(node: Node, layer_mask: int) -> void:
|
||||
|
||||
func _add_procedural_arms(weapon: Node3D) -> void:
|
||||
# Attach to weapon instead of model_root to avoid arms spinning on reload
|
||||
|
||||
var mat = StandardMaterial3D.new()
|
||||
mat.albedo_color = Color(0.2, 0.4, 0.8) # Player color
|
||||
mat.roughness = 0.8
|
||||
|
||||
# Right Arm (Main Grip)
|
||||
var r_arm = MeshInstance3D.new()
|
||||
var r_mesh = BoxMesh.new()
|
||||
r_mesh.size = Vector3(0.08, 0.7, 0.08)
|
||||
r_mesh.material = mat
|
||||
r_arm.mesh = r_mesh
|
||||
|
||||
var r_pivot = Node3D.new()
|
||||
var r_shoulder = Vector3(0.25, -0.3, 0.5)
|
||||
var r_hand = Vector3(0.04, -0.05, 0.05)
|
||||
r_pivot.position = r_shoulder
|
||||
r_pivot.look_at_from_position(r_shoulder, r_hand, Vector3.UP)
|
||||
|
||||
r_arm.rotation_degrees.x = 90 # Mesh points UP by default, we need it to point forward along -Z
|
||||
r_arm.position.z = -0.35
|
||||
r_pivot.add_child(r_arm)
|
||||
weapon.add_child(r_pivot)
|
||||
|
||||
# Left Arm (Foregrip)
|
||||
_build_arm(weapon, Vector3(0.25, -0.3, 0.5), Vector3(0.04, -0.05, 0.05))
|
||||
if "weapon_name" in weapon and weapon.weapon_name != "Knife":
|
||||
var l_arm = MeshInstance3D.new()
|
||||
var l_mesh = BoxMesh.new()
|
||||
l_mesh.size = Vector3(0.08, 0.7, 0.08)
|
||||
l_mesh.material = mat
|
||||
l_arm.mesh = l_mesh
|
||||
|
||||
var l_pivot = Node3D.new()
|
||||
var l_shoulder = Vector3(-0.25, -0.3, 0.4)
|
||||
var l_hand = Vector3(-0.02, -0.02, -0.3)
|
||||
l_pivot.position = l_shoulder
|
||||
l_pivot.look_at_from_position(l_shoulder, l_hand, Vector3.UP)
|
||||
|
||||
l_arm.rotation_degrees.x = 90
|
||||
l_arm.position.z = -0.35
|
||||
l_pivot.add_child(l_arm)
|
||||
weapon.add_child(l_pivot)
|
||||
_build_arm(weapon, Vector3(-0.25, -0.3, 0.4), Vector3(-0.02, -0.02, -0.3))
|
||||
|
||||
|
||||
## A first-person arm styled after the character skin: dark detached sleeve,
|
||||
## glowing cuff, bare hand — instead of the old featureless blue slab.
|
||||
func _build_arm(weapon: Node3D, shoulder: Vector3, hand: Vector3) -> void:
|
||||
var sleeve_mat = StandardMaterial3D.new()
|
||||
sleeve_mat.albedo_color = Color(0.10, 0.11, 0.14) # near-black sleeve
|
||||
sleeve_mat.roughness = 0.8
|
||||
var cuff_mat = StandardMaterial3D.new()
|
||||
cuff_mat.albedo_color = Color(0.25, 0.95, 0.90) # signature teal cuff
|
||||
cuff_mat.emission_enabled = true
|
||||
cuff_mat.emission = Color(0.10, 0.55, 0.52)
|
||||
var skin_mat = StandardMaterial3D.new()
|
||||
skin_mat.albedo_color = Color(0.98, 0.88, 0.82) # skin
|
||||
skin_mat.roughness = 0.9
|
||||
|
||||
var pivot = Node3D.new()
|
||||
pivot.position = shoulder
|
||||
pivot.look_at_from_position(shoulder, hand, Vector3.UP)
|
||||
|
||||
var sleeve = MeshInstance3D.new()
|
||||
var sleeve_mesh = BoxMesh.new()
|
||||
sleeve_mesh.size = Vector3(0.075, 0.075, 0.46)
|
||||
sleeve_mesh.material = sleeve_mat
|
||||
sleeve.mesh = sleeve_mesh
|
||||
sleeve.position.z = -0.27
|
||||
pivot.add_child(sleeve)
|
||||
|
||||
var cuff = MeshInstance3D.new()
|
||||
var cuff_mesh = BoxMesh.new()
|
||||
cuff_mesh.size = Vector3(0.085, 0.085, 0.05)
|
||||
cuff_mesh.material = cuff_mat
|
||||
cuff.mesh = cuff_mesh
|
||||
cuff.position.z = -0.52
|
||||
pivot.add_child(cuff)
|
||||
|
||||
var hand_box = MeshInstance3D.new()
|
||||
var hand_mesh = BoxMesh.new()
|
||||
hand_mesh.size = Vector3(0.06, 0.055, 0.12)
|
||||
hand_mesh.material = skin_mat
|
||||
hand_box.mesh = hand_mesh
|
||||
hand_box.position.z = -0.60
|
||||
pivot.add_child(hand_box)
|
||||
|
||||
weapon.add_child(pivot)
|
||||
|
||||
func _equip_slot(slot: int) -> void:
|
||||
if weapons.has(active_slot):
|
||||
|
||||
Reference in New Issue
Block a user