Help, I have been working on a topdown shooter and I have been working on level design and I have put down more than one enemy and i get this error: Invalid call. Nonexistent function ‘velocity_toward’ in base ‘Nil’, here is the code for the enemy ai:
extends Node2D
signal state_changed(new_state)
enum State {
PATROL,
ENGAGE
}
@onready var player_detection_zone = $playerdetectionzone
@onready var patrol_timer = $patroltimer
var current_state: int = -1 : set = set_state
var actor: CharacterBody2D = null
var player: Player = null
var weapon: Weapon = null
var origin: Vector2 = Vector2.ZERO
var patrol_location: Vector2 = Vector2.ZERO
var patrol_location_reached := false
var actor_velocity: Vector2 = Vector2.ZERO
func _ready() -> void:
set_state(State.PATROL)
func _process(delta: float) -> void:
match current_state:
State.PATROL:
if not patrol_location_reached:
actor.rotation = lerp(actor.rotation, actor.global_position.direction_to(patrol_location).angle(), 0.1)
actor.velocity = actor_velocity
actor.move_and_slide()
actor.rotate_toward(patrol_location)
if actor.global_position.distance_to(patrol_location) < 5:
patrol_location_reached = true
actor_velocity = Vector2.ZERO
patrol_timer.start()
State.ENGAGE:
if player != null and weapon != null:
var angle_to_player = actor.global_position.direction_to(player.global_position).angle()
actor.rotate_toward(player.global_position)
if abs(actor.rotation - angle_to_player) < 0.1:
weapon.shoot()
else:
print('In the engage state but no weapon or player')
_:
print("ERROR: FOUND A STATE FOR OUR ENEMY THAT SHOULD NOT EXIST")
func initialize(actor, weapon: Weapon):
self.actor = actor
self.weapon = weapon
func set_state(new_state: int):
if new_state == current_state:
return
if new_state == State.PATROL:
origin = global_position
patrol_timer.start()
patrol_location_reached = true
current_state = new_state
emit_signal("state_changed", current_state)
func _on_playerdetectionzone_body_entered(body: Node) -> void:
if body.is_in_group("player"):
set_state(State.ENGAGE)
player = body
func _on_playerdetectionzone_body_exited(body) -> void:
if player and body == player:
set_state(State.PATROL)
player = null
func _on_patroltimer_timeout() -> void:
var patrol_range = 50
var random_x = randf_range(-patrol_range, patrol_range)
var random_y = randf_range(-patrol_range, patrol_range)
patrol_location = Vector2(random_x, random_y) + origin
patrol_location_reached = false
actor_velocity = actor.velocity_toward(patrol_location)
here is the code for the enemy itself:
extends CharacterBody2D
signal killed(points)
@onready var health_stat = $Health
@onready var ai = $AI
@onready var weapon = $weapon
@export var speed: int = 100
@export var points: int = 100
func _ready() -> void:
ai.initialize(self, weapon)
func rotate_toward(location: Vector2):
rotation = lerp(rotation, global_position.direction_to(location).angle(), 0.1)
func velocity_toward(location: Vector2) -> Vector2:
return global_position.direction_to(location) * speed
func handle_hit():
health_stat.health -= 20
if health_stat.health <= 0:
killed.emit(points)
queue_free()
i don’t know what’s happening, when there is one enemy it works fine, but when there is multiple, it crashes.
here is a screenshot:
i have been following a bunch of tutorials for godot 3 and i have been using godot 4. help would be appreciated, thank you !