I'm trying to create a laser weapon for my game but I've been struggling to get both the damage (raycast) and beam (Line2D) to both go to the correct target position. Currently, the the Line2D representing the beam is drawing in the correction direction, but when the player fires any direction other than towards (1, 0), the raycast doesn't appear to cast in the expected direction.
I think I've narrowed the problem to how I am applying transforms to the raycast and the Line2D, but I've reached end of my knowledge on how to proceed further to correct it. This the relevant part of the player scene:
- Player (KinematicBody2D; scene root)
- BodyPivot (Position2D)
- Body (Sprite)
- CurrentWeaponSprite (Sprite)
- Muzzle (Position2D)
- Inventory (Node)
- LaserRifle (Area2D; scene instance)
- Sprite
The 'CurrentWeaponSprite' node rotates like turret to aim wherever the player moves the mouse, while all the other node do not rotate.
I'm using the following code:
"""LaserRifle.gd"""
extends Area2D
var DAMAGE = 5
shot_duration = 0.25
knockback_speed = 50
knockback_duration = 0.12
stun_duration = 0.25
var beam
var beam_color = Color.crimson
func shoot(projectile_start_position):
muzzle_position = projectile_start_position
var result = _cast_ray(muzzle_position)
if result:
_create_beam(muzzle_position, result)
_inflict_damage(result)
yield(get_tree().create_timer(shot_duration), "timeout")
_destroy_beam()
func _cast_ray(projectile_start_position):
var CurrentWeaponSprite = CarriedBy.current_weapon_sprite()
var space_state = get_world_2d().direct_space_state
var result = space_state.intersect_ray(projectile_start_position, projectile_start_position + CarriedBy.transform.x * 1000, [self, CarriedBy])
func _create_beam(muzzle_position, result):
var CurrentWeaponSprite = CarriedBy.current_weapon_sprite() # The var CarriedBy is a reference to the 'actor' using the weapon.
beam = Line2D.new()
CurrentWeaponSprite.get_node("Muzzle").add_child(beam) # 'Muzzle' node is a Position2D node.
beam.width = 2
beam.default_color = beam_color
beam.end_cap_mode = Line2D.LINE_CAP_ROUND
beam.add_point(CurrentWeaponSprite.get_node("Muzzle").position)
beam.add_point(CarriedBy.transform.xform_inv(result.position))global coordiantes to local.
func _destroy_beam():
beam.queue_free()
func _inflict_damage(collision_info):
if collision_info.collider.has_node("Health"):
collision_info.collider.take_damage(DAMAGE, self, stun_duration, knockback_speed, knockback_duration)
Any suggestions on how I might fix this issue?