Godot Version
Godot 4.7.2
Question
I’m following this video (Make better 3D by State machine in Godot 4 by applemincraft) but the statemachine wont call on the enemywander script even though its a child of it
If you share code, please wrap it inside three backticks or replace the code in the next block:
extends Node
class_name StateMachine
@export var Initialstate: State
var current_state: State = null
var states: Dictionary = {}
func _ready() -> void:
for child in get_children():
if child is State:
states[child.name.to_lower()] = child
child.Transitioned.connect(on_child_transitioned)
if Initialstate:
current_state = Initialstate
Initialstate.enter()
func _process(delta: float) -> void:
if current_state:
current_state.process(delta)
func _physics_process(delta: float) -> void:
if current_state:
current_state.process(delta)
func on_child_transitioned(state, new_state_name):
if state != current_state:
return
var new_state = states[new_state_name.to_lower()]
if current_state:
current_state.exit()
new_state.enter()
Is there a function called process() in enemywander script?
yes
func _process(delta: float) -> void:
if wander_time < 0.0:
randomize_variables()
wander_time -= delta
did I miss something?
That’s _process(), not process()
then no, this is the only thing with the word process should I add process()?
What does the tutorial say?
it said nothing about process() it just works for them
Then just do exactly what they do.
it still doesn’t work it is on an earlier version do you know of any way or tutorial that can make enemies surround you before attacking or at least stop before?
The first step would be moving towards the player, that can be pretty hard and depends greatly on the type of game you are making.
Assuming it’s a 3d game we can give enemies a “sight” radius with an Area3D and a collision shape as it’s child (with what ever shape is appropriate for their “sight”). The area has a body_entered signal we can use to detect and store the player.
Then in your enemy’s physics process they move towards the player if they have seen them, and stop moving if they are very close.
extends CharacterBody3D
class_name Enemy
const SPEED: float = 5
const MIN_DISTANCE: float = 1
var target_player: Player = null
func _on_sight_body_entered(body: Node3D) -> void:
# `is Player` assumes your player script has `class_name Player` defined
if body is Player:
# I saw the player, keep track of them
target_player = body
func _physics_process(delta: float) -> void:
if target_player:
# I saw the player, move towards them
var direction: Vector3 = global_position.direction_to(target_player.global_position)
var distance: float = global_position.distance_to(target_player.global_position)
if distance < MIN_DISTANCE:
# unless I'm already very close
velocity = Vector3.ZERO
else:
velocity = direction * SPEED
else:
# I have not seen the player, stay still
velocity = Vector3.ZERO
move_and_slide()
This error doesn’t have anything to do with versions. It’s simple. Your StateMachine script is trying to call process() in EnemyWander script. The function you got there is _process(). Although it looks similar, this is a different name (every character matters in naming), so the caller cannot find the function process() in the script EnemyWander and hence it throws an error, complaining that the function doesn’t exist.
In order for error to go away there needs to be a function named process() in EnemyWander. Did you accidentally name that function _process() instead of process()?