Help with Raycast2D not detecting

Godot Version

4.2.2

Question

Im having trouble with raycast2D in script not detecting hits.

Heres my script for the raycast2Ds

extends Node2D

#Gun Stats
var Damage : int = 10
var KnockbackForce : float = 10
var ReloadTime : float = 1 # secs
var Ammo : float = 3
var AttackSpeed : float = 0.5 # secs
var BulletsPerFire : float = 2 # amount of bullets that come out per click
var BulletRange : float = 300 # how far a bullet raycast goes before ending
var AutoFire : bool = true

var CanFire : bool = true

func _process(_delta):
	if AutoFire == true && Input.is_action_pressed("Fire") && CanFire == true:
		for index in BulletsPerFire:
			shootGun()
	if AutoFire == false && Input.is_action_just_pressed("Fire") && CanFire == true:
		for index in BulletsPerFire:
			shootGun()
	rotateGun()

func shootGun():
	CanFire = false
	
	var ray = RayCast2D.new()
	ray.exclude_parent = true
	ray.collision_mask = 2
	ray.position = $WeaponPivot/BulletSpawnPoint.position
	ray.target_position.y = randf_range(-5, 5)
	ray.target_position.x = BulletRange
	ray.rotation = $WeaponPivot.rotation
	ray.enabled = true
	
	#shows raycast debug line
	var line = Line2D.new()
	line.width = 1
	line.add_point(ray.position)
	line.add_point(ray.target_position)
	line.rotation = $WeaponPivot.rotation
	#
	
	#shows debug startpos and endpos for raycast
	$WeaponPivot/StartPos.position = ray.position
	$WeaponPivot/EndPos.position = ray.target_position
	#
	
	add_child(line)
	add_child(ray) 
	
	if ray.is_colliding():
		print("hit")
	
	cockGun()
	
	await get_tree().create_timer(0.1).timeout
	
	ray.queue_free()
	line.queue_free()

func rotateGun():
	$WeaponPivot.look_at(get_global_mouse_position())
	if get_local_mouse_position().x < 0:
		$WeaponPivot/BulletSpawnPoint.position = Vector2(30, 2)
		$WeaponPivot/GunSprite2D.flip_v = true
	else :
		$WeaponPivot/BulletSpawnPoint.position = Vector2(30, -2)
		$WeaponPivot/GunSprite2D.flip_v = false

func cockGun():
	await get_tree().create_timer(AttackSpeed).timeout
	CanFire = true

the var ray is suppose to check if it hits in the layer mash “2” after it is added to the scene, but it doesn’t print.

image
Test Enemy Layout
image
Test Enemy Collision

image
Raycasts are added to Gun node2d as a child

Heyo,

first off all i would consider instantiating the ray once in _ready() and reusing it for every shot. This can become particularly important with a higher rate of fire.

I’m not an expert on RayCast2D and it’s implementation but i have had similar issues. Try calling force_raycast_update() on the ray before checking for collisions.

I’m def not qualified to explain why this is necessary but iirc it’s either a bug that raycasts don’t collide in the same frame they’re being added to the scene OR it could be because their get_collision… functions return the cached collision from last frame (not sure if that’s actually the case tho). Or honestly anything else but that’s how i’ve always thought of it.

Sorry for bad formatting I didn’t find code formatting options on mobile.

1 Like

Tysm, not using force_raycast_update() was the issue ! :slightly_smiling_face: