I think I don't understand the match function

Godot Version

4.2.1.stable

Question

I am pretty new to this and have been searching for a while but either didn’t look in the right place or didn’t know enough to abstract the stuff I found to my situation.

This is an NPC I want to make. It should wander in a small area by default, flee from the player when they enter an area around it and go towards a fish(static body 2D) the player can throw when that lands in the area.

I tried to do this with a very simple state machine, since this is my very first project and I am figuring stuff out as I go.
I think I may have misunderstood the match function, or is there something else glaringly obvious I just didn’t see/understand?

I have basic programming knowledge, just not with Godot/GD Script and am also pretty rusty.

Every help is appreciated. If this was solved somewhere else please let me know, i am kind of overwhelmed by the amount of information out there :sweat_smile:

extends CharacterBody2D
class_name Penglin

var move_direction: Vector2
var wander_time: float
var current_state = WANDER
const speed = 20

enum {WANDER, FEED, FLEE}

func _ready():
	randomize_wander()

func _process(delta):
	match current_state:
		WANDER:
			randomize_wander()
			if wander_time > 0:
				wander_time -= delta
				
			else:
				randomize_wander()
			move(delta)
		FEED:
			move(delta)
		FLEE:
			move(delta)

func move(delta):
	position = move_direction * speed * delta

func _on_awareness_zone_body_entered(body):
	if body == Player:
		current_state = FLEE
		move_direction = global_position.bounce(body.global_position)
	else:
		current_state = FEED
		move_direction = (body.global_position - position).normalized()

func _on_awareness_zone_body_exited(body):
	if body == Player:
		current_state = WANDER
	else:
		current_state = FEED
		
func randomize_wander():
	move_direction = Vector2(randf_range(-1, 1), randf_range(-1, 1)).normalized()
	wander_time = randf_range(1, 3)

randomize_wander() is called every frame during the WANDER state because you call it before the if statement. I guess that’s not intended.
edit: if you just want to call it once when you switch to WANDER state you should call it inside _on_awareness_zone_body_exited() when you set current_state.

And normally you have to use move_and_slide() to move a characterbody, something like this:

func move(delta):
    velocity = move_direction * speed
    move_and_slide()
1 Like

Also, this part

position = move_direction * speed * delta

sets the position to the same value each frame until move_direction is changed. Usually when you change position directly you want to add to the position. But yeah like the poster above said you should use move_and_slide.

2 Likes

Thank you, now it at least moves.

I still seem to have done something wrong with the states, since the direction doesn’t change if the player gets close.

Not sure what bounce does off the top of my head but this should give you the direction away from the body (player):

move_direction = body.global_position.direction_to(global_position)

oh also, try if body is Player:

1 Like

Okay great, thank you so much for your help!

I finally wrapped my head around it, I think :slightly_smiling_face:

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.