fix: awp fov #11

Merged
Dotts merged 4 commits from feat/7-adding-first-person-model into main 2026-06-06 09:11:39 -07:00
Showing only changes of commit c9d18ffe23 - Show all commits
+52 -8
View File
@@ -12,8 +12,7 @@ func _init() -> void:
max_range = 100.0
automatic = true
spread_angle = 0.02
projectile_speed = 60.0 # Fast but requires lead
projectile_speed = 90.0 # Extremely fast, less lead and drop
projectile_gravity = 5.0 # Slight drop
func _build_model() -> void:
@@ -106,18 +105,63 @@ func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
mesh_instance.rotation.x = deg_to_rad(-90)
proj.add_child(mesh_instance)
# Tracer streak
var tracer = MeshInstance3D.new()
var t_mesh = CylinderMesh.new()
t_mesh.top_radius = 0.02
t_mesh.bottom_radius = 0.0
t_mesh.height = 1.5
var t_mat = StandardMaterial3D.new()
t_mat.albedo_color = Color(1.0, 0.8, 0.1) # Bright yellow/orange
t_mat.emission_enabled = true
t_mat.emission = Color(1.0, 0.8, 0.1)
t_mat.emission_energy_multiplier = 3.0
t_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
t_mat.albedo_color.a = 0.6
t_mesh.material = t_mat
tracer.mesh = t_mesh
tracer.rotation.x = deg_to_rad(-90)
tracer.position.z = 0.75 # Trail behind the nail
proj.add_child(tracer)
var spawn_pos = origin
var actual_fire_dir = fire_dir
if muzzle_flash and camera:
spawn_pos = muzzle_flash.global_position
# Map the position through the viewmodel camera to fix FOV mismatch
var wman = get_parent()
if wman and "vm_camera" in wman and is_instance_valid(wman.vm_camera):
if wman.vm_camera.is_position_behind(muzzle_flash.global_position) == false:
var screen_pos = wman.vm_camera.unproject_position(muzzle_flash.global_position)
var dist = camera.global_position.distance_to(muzzle_flash.global_position)
spawn_pos = camera.project_position(screen_pos, dist)
var target_pos = origin + fire_dir * max_range
var space_state = camera.get_world_3d().direct_space_state
var query = PhysicsRayQueryParameters3D.create(origin, target_pos)
if player:
query.exclude = [player.get_rid()]
var result = space_state.intersect_ray(query)
if result:
target_pos = result.position
actual_fire_dir = (target_pos - spawn_pos).normalized()
# Projectile rotation so it faces velocity
var up_vec = Vector3.UP
if abs(fire_dir.dot(up_vec)) > 0.99:
if abs(actual_fire_dir.dot(up_vec)) > 0.99:
up_vec = Vector3.RIGHT
proj.transform.basis = Basis.looking_at(fire_dir, up_vec)
proj.position = muzzle_flash.global_position if muzzle_flash else origin
proj.transform.basis = Basis.looking_at(actual_fire_dir, up_vec)
# Push the projectile forward slightly so the 1.5m long tracer tail
# doesn't clip backward past the gun and look like it's coming from beside the player's head.
proj.position = spawn_pos + actual_fire_dir * 1.5
proj.logical_source = origin
proj.velocity = fire_dir * projectile_speed
proj.velocity = actual_fire_dir * projectile_speed
if player:
proj.velocity += fire_dir * max(0.0, player.velocity.dot(fire_dir))
proj.velocity += actual_fire_dir * max(0.0, player.velocity.dot(actual_fire_dir))
proj.damage = base_damage
proj.min_damage = min_damage
proj.falloff_start = falloff_start