@@ -90,6 +90,9 @@ var _previous_state: State
9090# The player that's being detected.
9191var _player : Node2D
9292
93+ # A marker to the player's last seen position.
94+ var _investigating_target : Node2D
95+
9396## Area that represents the sight of the guard. If a player is in this area
9497## and there are no walls in between detected by [member sight_ray_cast], it
9598## means the player is in sight.
@@ -108,6 +111,9 @@ var _player: Node2D
108111## Behavior to use when returning.
109112@onready var returning_behavior : PointsWalkBehavior = % ReturningBehavior
110113
114+ ## Behavior to use when investigating.
115+ @onready var investigating_behavior : FollowWalkBehavior = % InvestigatingBehavior
116+
111117## Reference to the node controlling the AnimationPlayer for walking / being idle,
112118## so it can be disabled to play the alerted animation.
113119@onready
@@ -117,8 +123,6 @@ var character_animation_player_behavior: CharacterAnimationPlayerBehavior = %Cha
117123## Timer for the waiting state.
118124@onready var waiting_timer : Timer = % WaitingTimer
119125
120- ## Handles the velocity and movement of the guard.
121- @onready var guard_movement : GuardMovement = % GuardMovement
122126@onready var animated_sprite_2d : AnimatedSprite2D = % AnimatedSprite2D
123127@onready var animation_player : AnimationPlayer = $ AnimationPlayer
124128@onready var _alert_sound : AudioStreamPlayer = % AlertSound
@@ -151,16 +155,16 @@ func _ready() -> void:
151155
152156 patrolling_behavior .speeds .walk_speed = move_speed
153157 returning_behavior .speeds .walk_speed = move_speed
158+ investigating_behavior .speeds .walk_speed = move_speed
159+
160+ _investigating_target = Node2D .new ()
154161
155162 _set_patrol_path (patrol_path )
156163 _set_sprite_frames (sprite_frames )
157164
158165 if detection_area :
159166 detection_area .scale = Vector2 .ONE * detection_area_scale
160167
161- guard_movement .destination_reached .connect (self ._on_destination_reached )
162- guard_movement .path_blocked .connect (self ._on_path_blocked )
163-
164168 # Wait 2 frames before starting to match backwards compatibility.
165169 if not Engine .is_editor_hint ():
166170 await get_tree ().process_frame
@@ -175,13 +179,6 @@ func _process(delta: float) -> void:
175179 if Engine .is_editor_hint () and not move_while_in_editor :
176180 return
177181
178- match state :
179- State .WAITING , State .INVESTIGATING :
180- guard_movement .move ()
181- State .DETECTING :
182- if _previous_state != State .PATROLLING :
183- guard_movement .move ()
184-
185182 if state != State .ALERTED :
186183 _update_player_awareness (delta )
187184
@@ -235,21 +232,6 @@ func _update_debug_info() -> void:
235232 )
236233
237234
238- ## What happens when the guard reached the point it was walking towards
239- func _on_destination_reached () -> void :
240- match state :
241- State .INVESTIGATING :
242- state = State .WAITING
243-
244-
245- ## What happens if the guard cannot reach their destination because it got
246- ## stuck with a collider.
247- func _on_path_blocked () -> void :
248- match state :
249- State .INVESTIGATING :
250- state = State .RETURNING
251-
252-
253235func _set_state (new_state : State ) -> void :
254236 if state == new_state :
255237 return
@@ -261,32 +243,38 @@ func _set_state(new_state: State) -> void:
261243 State .PATROLLING :
262244 patrolling_behavior .process_mode = Node .PROCESS_MODE_INHERIT
263245 returning_behavior .process_mode = Node .PROCESS_MODE_DISABLED
246+ investigating_behavior .process_mode = Node .PROCESS_MODE_DISABLED
264247 State .DETECTING :
265248 if _previous_state != State .PATROLLING :
266249 patrolling_behavior .process_mode = Node .PROCESS_MODE_DISABLED
250+ investigating_behavior .process_mode = Node .PROCESS_MODE_INHERIT
251+ else :
252+ investigating_behavior .process_mode = Node .PROCESS_MODE_DISABLED
267253 returning_behavior .process_mode = Node .PROCESS_MODE_DISABLED
268254 if not _alert_sound .playing :
269255 _alert_sound .play ()
270256 State .ALERTED :
271257 patrolling_behavior .process_mode = Node .PROCESS_MODE_DISABLED
272258 returning_behavior .process_mode = Node .PROCESS_MODE_DISABLED
259+ investigating_behavior .process_mode = Node .PROCESS_MODE_DISABLED
273260 character_animation_player_behavior .process_mode = Node .PROCESS_MODE_DISABLED
274261 if not _alert_sound .playing :
275262 _alert_sound .play ()
276263 animation_player .play (& "alerted" )
277264 player_awareness .ratio = 1.0
278265 player_awareness .tint_progress = Color .RED
279266 player_awareness .visible = true
280- guard_movement .stop_moving ()
281267 State .INVESTIGATING :
282268 patrolling_behavior .process_mode = Node .PROCESS_MODE_DISABLED
283269 returning_behavior .process_mode = Node .PROCESS_MODE_DISABLED
270+ investigating_behavior .process_mode = Node .PROCESS_MODE_INHERIT
284271 breadcrumbs .push_back (global_position )
285272 State .WAITING :
286273 patrolling_behavior .process_mode = Node .PROCESS_MODE_DISABLED
287274 returning_behavior .process_mode = Node .PROCESS_MODE_DISABLED
275+ investigating_behavior .process_mode = Node .PROCESS_MODE_DISABLED
288276 waiting_timer .start ()
289- guard_movement . stop_moving ()
277+ velocity = Vector2 . ZERO
290278 State .RETURNING :
291279 patrolling_behavior .process_mode = Node .PROCESS_MODE_DISABLED
292280 var returning_path := Path2D .new ()
@@ -297,8 +285,8 @@ func _set_state(new_state: State) -> void:
297285 returning_path .curve .add_point (point )
298286 returning_behavior .walking_path = returning_path
299287 returning_behavior .process_mode = Node .PROCESS_MODE_INHERIT
288+ investigating_behavior .process_mode = Node .PROCESS_MODE_DISABLED
300289 breadcrumbs = []
301- guard_movement .stop_moving ()
302290
303291
304292## Checks if a straight line can be traced from the Guard to a certain point.
@@ -426,11 +414,12 @@ func _on_detection_area_body_entered(body: Node2D) -> void:
426414func _on_detection_area_body_exited (body : Node2D ) -> void :
427415 _player = null
428416 if state == State .DETECTING :
429- guard_movement .stop_moving ()
417+ _investigating_target .global_position = body .global_position
418+ investigating_behavior .target = _investigating_target
430419 state = State .INVESTIGATING
431- guard_movement .set_destination (body .global_position )
432420 elif state == State .INVESTIGATING :
433- guard_movement .set_destination (body .global_position )
421+ _investigating_target .global_position = body .global_position
422+ investigating_behavior .target = _investigating_target
434423
435424
436425func _on_waiting_timer_timeout () -> void :
@@ -451,3 +440,12 @@ func _on_patrolling_behavior_got_stuck() -> void:
451440
452441func _on_returning_behavior_ending_reached () -> void :
453442 state = State .PATROLLING
443+
444+
445+ func _on_investigating_behavior_target_reached_changed (is_reached : bool ) -> void :
446+ if is_reached :
447+ state = State .WAITING
448+
449+
450+ func _on_investigating_behavior_got_stuck () -> void :
451+ state = State .RETURNING
0 commit comments