.            ★.        . blessfrey.me ..          ☆        .

blessfrey gdd - pathfinding

Pathfinding programmatically moves an entity towards a point.


move to pick up an item

If an entity decides to pick up a floor item, UserControl.gd/pickup(floor_item) checks the range. If too far away, it will trigger MoveToDestination.gd/pickup_setup(floor_item).


Signals are disconnected, track is made true, 'item_arrived' signal is connected to UserControl/Move, and the goal target is set.


MoveToDestination.gd's Execute method constantly loops between path_to_point() and choose_velocity().


path_to_point calls cancel on the player and path_to_object(goal_target). Mobile.gd/path_to_object(goal_target) sets the floor item as the next then reassesses the path with each call. If there is no current_dot, dots are set between the user and the goal_target and the method ends. Otherwise, the last_dot is either the last dot or the current_dot. If the goal hasn't moved, the method ends. If the goal is further, the path is wholly or partially recalculated. If the goal is nearer, the path is recalculated between the last_dot and the goal.


choose_velocity() sets the entity's body's internal velocity to current_dot - current_pos. mobileBody.gd/_process(delta) sets its physics_body_node's move_and_collide to velocity (judged from internal velocity) * speed * delta * KnowledgeBase.logic_time, publishing "moved" and the entity to the MessageBus.


The MessageBus's Moved.gd handler will judge progress and emit a signal. Since "reached", "arrived", etc are connected during MoveToDestination's Enter phase, handle_moved_result handles the package. If it is "arrived" and track is true, 'item_arrived' signal is emitted, the first waypoint is popped off, and the entity calls clear_movement.


MoveToDestination.gd/_on_item_arrived(floor_item) calls arrived to disconnect signals, set track to false, and clear the entity's movement. Then it calls item.pick_up().pick_up().


challenges/known issues

Navigation2D and get_simple_path will be removed in a future version of Godot.


works for...