fix: 3rd person and first person views
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user