1use gizmo_math::Vec3;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
4pub enum NavAgentState {
5 Idle,
6 Moving,
7 Reached,
8 Stuck,
9}
10
11#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
12pub struct NavAgentRecalcState {
13 pub timer: f32,
14 pub interval: f32,
15 pub last_target_pos: Option<Vec3>,
16}
17
18#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
19pub struct NavAgent {
20 pub target: Option<Vec3>,
21 path: Vec<Vec3>,
22 current_path_index: usize, pub state: NavAgentState,
24 pub recalc: NavAgentRecalcState,
25 pub max_speed: f32,
26 pub steering_force: f32,
27 pub arrival_radius: f32,
28 pub stuck_timer: f32,
29 pub last_agent_pos: Option<Vec3>,
30}
31
32impl NavAgent {
33 pub fn new(max_speed: f32, steering_force: f32, arrival_radius: f32) -> Self {
34 Self {
35 target: None,
36 path: Vec::new(),
37 current_path_index: 0,
38 state: NavAgentState::Idle,
39 recalc: NavAgentRecalcState {
40 timer: 0.0,
41 interval: 0.5,
42 last_target_pos: None,
43 },
44 max_speed,
45 steering_force,
46 arrival_radius,
47 stuck_timer: 0.0,
48 last_agent_pos: None,
49 }
50 }
51
52 pub fn set_path(&mut self, path: Vec<Vec3>) {
53 self.path = path;
54 self.current_path_index = 0;
55 }
56
57 pub fn clear_path(&mut self) {
58 self.path.clear();
59 self.current_path_index = 0;
60 }
61
62 pub fn current_waypoint(&self) -> Option<&Vec3> {
63 self.path.get(self.current_path_index)
64 }
65
66 pub fn advance(&mut self) {
67 self.current_path_index += 1;
68 }
69
70 pub fn is_done(&self) -> bool {
71 self.current_path_index >= self.path.len()
72 }
73
74 pub fn path_len(&self) -> usize {
75 self.path.len()
76 }
77
78 pub fn path_index(&self) -> usize {
79 self.current_path_index
80 }
81
82 pub fn set_target(&mut self, target: Vec3) {
83 self.target = Some(target);
84 self.recalc.timer = 0.0; }
86}
87
88impl Default for NavAgent {
89 fn default() -> Self {
90 Self::new(5.0, 10.0, 0.5)
91 }
92}
93
94gizmo_core::impl_component!(NavAgent);