how to make the enemy fire at the player when he is in range of him

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Nightmare
Player script


extends KinematicBody2D

signal health(health)
signal max_health(health)

var velocity = Vector2()
var on_ground = false
var is_attacking = false
var is_dead = false
var fail_safe = false
var is_left = false
var is_right = false
var health_setup = false

const FLOOR = Vector2(0, -1)
const SPEED = 500
const GRAVITY = 30
const JUMP_POWER = -700
const FIREBALL = preload("res://Fireball.tscn")
const STILL = 0

export(float) var max_health = 100

onready var health = max_health
onready var invulnerbillity_timer = $AnimationPlayer


func _process(_delta):
	if health_setup == false:
		emit_signal("max_health", max_health)
		emit_signal("health", max_health)
		health_setup = true
		print("hi")

func _physics_process(_delta):
	if fail_safe == false:
		if is_dead == false:
			if Input.is_action_pressed("move_right"):
				if is_attacking == false || is_on_floor() == false && is_dead == false:
					is_left = false
					is_right = true
					velocity.x = SPEED
					if is_attacking == false:
						$AnimatedSprite.flip_h = false
						if on_ground != true:
							pass
						else:
							$AnimatedSprite.play("walk")
						if sign($Position2D.position.x) == -1:
							$Position2D.position.x *= -1
			elif Input.is_action_pressed("move_left"):
				if is_attacking == false || is_on_floor() == false && is_dead == false:
					is_right = false
					is_left = true
					velocity.x = -SPEED
					if is_attacking == false:
						$AnimatedSprite.flip_h = true
						if on_ground != true:
							pass
						else:
							$AnimatedSprite.play("walk")
						if sign($Position2D.position.x) == 1:
							$Position2D.position.x *= -1
			else:
				velocity.x = 0
				if on_ground == true && is_attacking == false:
					$AnimatedSprite.play("idle")
			
			
			if Input.is_action_just_pressed("my_action") && is_attacking == false:
				is_attacking = true
				$AnimatedSprite.play("attack")
				var fireball = FIREBALL.instance()
				if sign($Position2D.position.x) == 1:
					fireball.set_fireball_direction(1)
				else:
					fireball.set_fireball_direction(-1)
				get_parent().add_child(fireball)
				fireball.position = $Position2D.global_position
				
				
			
			if Input.is_action_pressed("jump"):
				if is_attacking == false:
					if on_ground == true:
							velocity.y = JUMP_POWER
							on_ground = false
					
			
			velocity.y += GRAVITY
			
			if is_on_floor():
				if on_ground == false:
					is_attacking = false
				on_ground = true
			else:
				if is_attacking == false:
					on_ground = false
					if velocity.y < 0:
						$AnimatedSprite.play("jump")
						
			velocity = move_and_slide(velocity, FLOOR)
			
			if get_slide_count() > 0:
				for i in range(get_slide_count()):
					if "Enemy" in get_slide_collision(i).collider.name:
						dead()
					if "scorpion" in get_slide_collision(i).collider.name:
						dead()
			
			if health < 100:
				if Input.is_action_just_pressed("test_spam_heal"):
					health += 25
					emit_signal("health", health)
					
			


func dead():
	if $invulnerbillityTimer.is_stopped():
		health -= 25
		emit_signal("health", health)
		on_hit()
		if health <= 0:
			$Control.visible = false
			fail_safe = true
			velocity = Vector2(0, 0)
			$CollisionShape2D.set_deferred("disabled", true)
			$AnimatedSprite.play("death")
			$Timer.start()
	

func on_hit():
	if health > 0:
		$CollisionShape2D2.disabled = false
		$CollisionShape2D.set_deferred("disabled", true)
		invulnerbillity_timer.play("hurt")
		invulnerbillity_timer.queue("invulnerbillity")
		$invulnerbillityTimer.start()


func _on_AnimatedSprite_animation_finished():
	is_attacking = false

func _on_Timer_timeout():
	get_tree().quit()


func _on_invulnerbillityTimer_timeout():
	invulnerbillity_timer.play("rest")
	$CollisionShape2D2.disabled = true
	$CollisionShape2D.set_deferred("disabled", false)```

Enemy script

extends KinematicBody2D

var velocity = Vector2()
var direction = 1
var is_dead = false
var is_hurt = false
var attack_anim = false
var health_check = false
var rng = RandomNumberGenerator.new()
var stun = false
var walk_cancel = false

const GRAVITY = 10
const FLOOR = Vector2(0, -1)

export(int) var speed = 100
export (float) var max_health = 200

onready var Player = get_node("/root/World/Player")
onready var health = max_health
const FIREBALL = preload("res://scorpion fireball.tscn")



func dead():
	rng.randomize()
	var my_random_number = rng.randi_range(0, 10.0)
	if my_random_number >= 10:
		health -= 50
		stun = true
	elif my_random_number <= 0:
		health -= 0
	else:
		health -= 25
	health_bar2()
	on_hit()
	if health <= 0:
		$Sprite.visible = false
		is_dead = true
		velocity = Vector2(0, 0)
		$CollisionShape2D.set_deferred("disabled", true)
		$AnimatedSprite.play("dead")
		$Timer.start()

func on_hit():
	if health > 0:
		$CollisionShape2D2.set_deferred("disabled", false)
		$CollisionShape2D.set_deferred("disabled", true)
		if stun == true:
			attack_anim = true
		walk_cancel = true
		$AnimatedSprite.play("hurt")
		$Timer2.start()

func _physics_process(_delta):
	if is_dead == false:
		if attack_anim == false:
			velocity.x = speed * direction
		velocity.y += GRAVITY
		
		if attack_anim == false:
			if direction == 1:
				$AnimatedSprite.flip_h = true
				if sign($Area2D2.position.x) == -1:
					$Area2D2.position.x *= -1
			elif direction == -1:
				$AnimatedSprite.flip_h = false
				if sign($Area2D2.position.x) == 1:
					$Area2D2.position.x *= -1
		if attack_anim == false:
			if walk_cancel == false:
				$AnimatedSprite.play("walk")
		
		velocity = move_and_slide(velocity, FLOOR)
			
		if is_on_wall():
			direction = direction * -1
			$RayCast2D.position.x *= -1
			$Sprite.position.x *= -1
			
		if get_slide_count() > 0:
			for i in range (get_slide_count()):
				if "Player" in get_slide_collision(i).collider.name:
					attack_anim = true
					$AnimatedSprite.play("attack")
					get_slide_collision(i).collider.dead()
					$Timer3.start()
					
					
		if $RayCast2D.is_colliding() == false:
			direction *= -1
			$RayCast2D.position.x *= -1
			$Sprite.position.x *= -1

func _on_Timer_timeout():
	queue_free()

func _on_Timer2_timeout():
	is_dead = false
	stun = false
	attack_anim = false
	walk_cancel = false
	$CollisionShape2D2.set_deferred("disabled", true)
	$CollisionShape2D.set_deferred("disabled", false)

func _on_Timer3_timeout():
	attack_anim = false

func health_bar2():
         pass

func _on_Area2D_body_entered(_body):
	if get_slide_count() > 0:
		for i in range (get_slide_count()):
			if "Player" in get_slide_collision(i).collider.name:
				attack_anim = true
				$AnimatedSprite.play("attack")
				get_slide_collision(i).collider.dead()

and my enemy fireball script


    extends Area2D
    
    const SPEED = 600
    var velocity = Vector2()
    var direction = 1
    func _ready():
    	pass
    
    func set_fireball_direction(dir):
    	direction = dir
    	if dir == -1:
    		$AnimatedSprite.flip_h = true
    
    func _physics_process(delta):
    	velocity.x = SPEED * delta * direction
    	translate(velocity)
    	$AnimatedSprite.play("shoot")
    
    
    func _on_VisibilityNotifier2D_screen_exited():
    	queue_free()
    
    
    func _on_scorpion_fireball_body_entered(body):
    	if "Player" in body.name:
    		body.dead()
    	queue_free()

how would i get the player to be constantly waiting for the player to appear in front of him then shoot at him when he is in a certain range and i dont want to go up i want to just left and right i also have no autoloads or plugins. and before you say yes i have 2 dead functions beacuse sometimes when doing the get_slide_collision(i) it wouldnt damage the player if he was walking behind the enemy
:bust_in_silhouette: Reply From: yrtv

RayCast2D.get_collision_point ( )
Range is just

position1.x - position2.x

no but like how do i get it to trigger when only the player enters the raycast like i have

if $RayCast2D2.is_colliding(): 
    pass

like how do i get

if body.name == "Player": 
get_parent().add_child("res://scorpion_fireball.tscn)

Nightmare | 2021-10-01 02:22

Simplest solution is:

  1. Create separate Collision layer for Player
  2. Set RayCast2D.set_cast_to() to range you want.
  3. Set RayCast2D.set_collision_mask() to only contain Player layer created in step 1.

Now ray can collide only with Player, and only if Player in range of cast_to

yrtv | 2021-10-01 07:22