fix: 3rd person and first person views

This commit is contained in:
DottsGit
2026-06-06 11:51:28 -04:00
parent 909b25548c
commit 3488b8e005
3 changed files with 124 additions and 11 deletions
+58 -5
View File
@@ -55,7 +55,7 @@ func _setup_viewmodel_viewport() -> void:
dir_light.light_energy = 0.5
add_child(dir_light)
func _process(delta: float) -> void:
func _process(_delta: float) -> void:
if is_instance_valid(vm_camera) and is_instance_valid(camera):
vm_camera.global_transform = camera.global_transform
vm_camera.fov = camera.fov
@@ -97,12 +97,18 @@ func _spawn_weapon(slot: int, weapon_id: String) -> void:
weapons[slot] = w
w.visible = false
w.set_process_input(false)
w.set_meta("script_path", script_path)
_add_procedural_arms(w)
# Set weapons to viewmodel layer
_set_layer_recursive(w, 1 << 19)
func _set_layer_recursive(node: Node, layer_mask: int) -> void:
if node is VisualInstance3D:
if node is GeometryInstance3D:
node.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
if node is Light3D:
# Lights (e.g. muzzle flash) illuminate both world and viewmodel
node.layers = 1 | layer_mask
@@ -112,6 +118,50 @@ func _set_layer_recursive(node: Node, layer_mask: int) -> void:
for child in node.get_children():
_set_layer_recursive(child, layer_mask)
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)
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)
func _equip_slot(slot: int) -> void:
if weapons.has(active_slot):
var w = weapons[active_slot]
@@ -128,10 +178,13 @@ func _equip_slot(slot: int) -> void:
var w = weapons[active_slot]
w.visible = true
w.set_process_input(true)
print("Equipped slot ", slot)
else:
print("Slot ", slot, " is empty!")
# Sync 3rd person weapon
if player and player.has_node("HumanoidModel"):
var humanoid = player.get_node("HumanoidModel")
if humanoid.has_method("set_weapon") and w.has_meta("script_path"):
humanoid.set_weapon(w.get_meta("script_path"))
func _input(event: InputEvent) -> void:
if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED:
return