extends CharacterBody3D enum Actions { Fishing, Relaxing, } @export var player: bool @export var action: Actions = Actions.Relaxing @export_category("Movement") @export_flags_3d_physics var raycast_mask var movement_speed: float = 2.0 var movement_target_position: Vector3 = Vector3(-3.0,0.0,3.5) @onready var navigation_agent: NavigationAgent3D = $NavigationAgent3D func _ready(): # These values need to be adjusted for the actor's speed # and the navigation layout. navigation_agent.path_desired_distance = 0.2 navigation_agent.target_desired_distance = 0.5 #actor_setup.call_deferred() func actor_setup(): # Wait for the first physics frame so the NavigationServer can sync. await get_tree().physics_frame var node = get_tree().get_nodes_in_group('FishingSpot')[0] # Now that the navigation map is no longer empty, set the movement target. set_movement_target(node.global_position) func set_movement_target(movement_target: Vector3): navigation_agent.set_target_position(movement_target) func get_point_from_mouse(): const RAY_LENGTH = 1000 var space_state = get_world_3d().direct_space_state var cam: Camera3D = $Pivot/Camera3D var mousepos = get_viewport().get_mouse_position() var origin = cam.project_ray_origin(mousepos) var end = origin + cam.project_ray_normal(mousepos) * RAY_LENGTH var query = PhysicsRayQueryParameters3D.create(origin, end, raycast_mask) query.collide_with_areas = true var result = space_state.intersect_ray(query) if result: return result.get("position") func _physics_process(delta): if Input.is_action_just_pressed("move"): var pos = get_point_from_mouse() if pos: set_movement_target(pos) if navigation_agent.is_navigation_finished(): return var current_agent_position: Vector3 = global_position var next_path_position: Vector3 = navigation_agent.get_next_path_position() velocity = current_agent_position.direction_to(next_path_position) * movement_speed move_and_slide()