76 lines
2.1 KiB
GDScript3
76 lines
2.1 KiB
GDScript3
|
extends Path
|
||
|
|
||
|
var _current_nav_path: PoolVector3Array
|
||
|
|
||
|
var _current_nav_index = 0
|
||
|
var _current_path_index = 1
|
||
|
|
||
|
var _arrived_distance_threshold = 0.1
|
||
|
|
||
|
export(float) var speed = 8
|
||
|
export(NodePath) var navigation_nodepath
|
||
|
export(NodePath) var body_nodepath
|
||
|
|
||
|
var navigation: Navigation
|
||
|
var body: KinematicBody
|
||
|
|
||
|
|
||
|
func _ready():
|
||
|
navigation = get_node(navigation_nodepath) as Navigation
|
||
|
body = get_node(body_nodepath) as KinematicBody
|
||
|
|
||
|
# Initialize the position
|
||
|
body.transform.origin = curve.get_point_position(0)
|
||
|
|
||
|
# Get the first goal
|
||
|
_get_new_navigation()
|
||
|
|
||
|
|
||
|
func _process(delta):
|
||
|
var current_goal = _get_current_goal()
|
||
|
|
||
|
# Move towards the current goal
|
||
|
var direction = (current_goal - _get_body_position()).normalized()
|
||
|
|
||
|
body.move_and_slide(direction * speed)
|
||
|
|
||
|
# Look towards that goal as well
|
||
|
body.look_at(_get_body_position() + direction, Vector3.UP)
|
||
|
|
||
|
|
||
|
# Returns the point we should currently be moving towards
|
||
|
func _get_current_goal():
|
||
|
# If we haven't arrived at the current goal, then that's still the goal
|
||
|
if _current_nav_path[_current_nav_index].distance_to(_get_body_position()) > _arrived_distance_threshold:
|
||
|
return _current_nav_path[_current_nav_index]
|
||
|
|
||
|
if _current_nav_index < _current_nav_path.size() - 1:
|
||
|
# We still have points left in the current navigation -> use the next one
|
||
|
_current_nav_index += 1
|
||
|
else:
|
||
|
# We're done following the current navigation to the next path point
|
||
|
if _current_path_index < curve.get_point_count() - 1:
|
||
|
# We still have points left in the path -> use the next one and generate the navigation to it
|
||
|
_current_path_index += 1
|
||
|
else:
|
||
|
# We're done following the path -> Go back to the start
|
||
|
_current_nav_index = 0
|
||
|
_current_path_index = 0
|
||
|
|
||
|
_get_new_navigation()
|
||
|
|
||
|
return _current_nav_path[_current_nav_index]
|
||
|
|
||
|
|
||
|
# Reset the navigation and build a new one for the current path index
|
||
|
func _get_new_navigation():
|
||
|
_current_nav_index = 0
|
||
|
|
||
|
var goal = curve.get_point_position(_current_path_index)
|
||
|
_current_nav_path = navigation.get_simple_path(_get_body_position(), goal)
|
||
|
|
||
|
|
||
|
# Return the current position of the body we're controlling
|
||
|
func _get_body_position():
|
||
|
return body.transform.origin
|