LookDirection

Struct LookDirection 

Source
pub struct LookDirection { /* private fields */ }
Expand description

A component that contains the direction an entity is looking, in degrees.

To avoid flagging anticheats, consider using Self::update when updating the values of this struct.

Implementations§

Source§

impl LookDirection

Source

pub fn new(y_rot: f32, x_rot: f32) -> Self

Create a new look direction and clamp the x_rot to the allowed values.

Source

pub fn y_rot(&self) -> f32

Returns yaw (left and right) in degrees.

Minecraft allows this to go outside of ±360°, so it won’t necessarily be in any range.

Examples found in repository?
azalea/examples/testbot/commands/debug.rs (line 95)
26pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
27    commands.register(literal("ping").executes(|ctx: &Ctx| {
28        let source = ctx.source.lock();
29        source.reply("pong!");
30        1
31    }));
32
33    commands.register(literal("disconnect").executes(|ctx: &Ctx| {
34        let source = ctx.source.lock();
35        source.bot.disconnect();
36        1
37    }));
38
39    commands.register(literal("whereami").executes(|ctx: &Ctx| {
40        let mut source = ctx.source.lock();
41        let Some(entity) = source.entity() else {
42            source.reply("You aren't in render distance!");
43            return 0;
44        };
45        let position = source.bot.entity_component::<Position>(entity);
46        source.reply(format!(
47            "You are at {}, {}, {}",
48            position.x, position.y, position.z
49        ));
50        1
51    }));
52
53    commands.register(literal("entityid").executes(|ctx: &Ctx| {
54        let mut source = ctx.source.lock();
55        let Some(entity) = source.entity() else {
56            source.reply("You aren't in render distance!");
57            return 0;
58        };
59        let entity_id = source.bot.entity_component::<MinecraftEntityId>(entity);
60        source.reply(format!(
61            "Your Minecraft ID is {} and your ECS ID is {entity:?}",
62            *entity_id
63        ));
64        1
65    }));
66
67    let whereareyou = |ctx: &Ctx| {
68        let source = ctx.source.lock();
69        let position = source.bot.position();
70        source.reply(format!(
71            "I'm at {}, {}, {}",
72            position.x, position.y, position.z
73        ));
74        1
75    };
76    commands.register(literal("whereareyou").executes(whereareyou));
77    commands.register(literal("pos").executes(whereareyou));
78
79    commands.register(literal("whoareyou").executes(|ctx: &Ctx| {
80        let source = ctx.source.lock();
81        source.reply(format!(
82            "I am {} ({}, {})",
83            source.bot.username(),
84            source.bot.uuid(),
85            source.bot.entity
86        ));
87        1
88    }));
89
90    commands.register(literal("getdirection").executes(|ctx: &Ctx| {
91        let source = ctx.source.lock();
92        let direction = source.bot.component::<LookDirection>();
93        source.reply(format!(
94            "I'm looking at {}, {}",
95            direction.y_rot(),
96            direction.x_rot()
97        ));
98        1
99    }));
100
101    commands.register(literal("health").executes(|ctx: &Ctx| {
102        let source = ctx.source.lock();
103
104        let health = source.bot.health();
105        source.reply(format!("I have {health} health"));
106        1
107    }));
108
109    commands.register(literal("lookingat").executes(|ctx: &Ctx| {
110        let source = ctx.source.lock();
111
112        let hit_result = source.bot.component::<HitResultComponent>();
113
114        match &*hit_result {
115            HitResult::Block(r) => {
116                if r.miss {
117                    source.reply("I'm not looking at anything");
118                    return 0;
119                }
120                let block_pos = r.block_pos;
121                let block = source.bot.world().read().get_block_state(block_pos);
122                source.reply(format!("I'm looking at {block:?} at {block_pos:?}"));
123            }
124            HitResult::Entity(r) => {
125                let entity_kind = *source.bot.entity_component::<EntityKindComponent>(r.entity);
126                source.reply(format!(
127                    "I'm looking at {entity_kind} ({:?}) at {}",
128                    r.entity, r.location
129                ));
130            }
131        }
132
133        1
134    }));
135
136    commands.register(literal("getblock").then(argument("x", integer()).then(
137        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
138            let source = ctx.source.lock();
139            let x = get_integer(ctx, "x").unwrap();
140            let y = get_integer(ctx, "y").unwrap();
141            let z = get_integer(ctx, "z").unwrap();
142            println!("getblock xyz {x} {y} {z}");
143            let block_pos = BlockPos::new(x, y, z);
144            let block = source.bot.world().read().get_block_state(block_pos);
145            source.reply(format!("BlockKind at {block_pos} is {block:?}"));
146            1
147        })),
148    )));
149    commands.register(literal("getfluid").then(argument("x", integer()).then(
150        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
151            let source = ctx.source.lock();
152            let x = get_integer(ctx, "x").unwrap();
153            let y = get_integer(ctx, "y").unwrap();
154            let z = get_integer(ctx, "z").unwrap();
155            println!("getfluid xyz {x} {y} {z}");
156            let block_pos = BlockPos::new(x, y, z);
157            let block = source.bot.world().read().get_fluid_state(block_pos);
158            source.reply(format!("Fluid at {block_pos} is {block:?}"));
159            1
160        })),
161    )));
162
163    commands.register(literal("pathfinderstate").executes(|ctx: &Ctx| {
164        let source = ctx.source.lock();
165        let pathfinder = source.bot.get_component::<Pathfinder>();
166        let Some(pathfinder) = pathfinder else {
167            source.reply("I don't have the Pathfinder ocmponent");
168            return 1;
169        };
170        source.reply(format!(
171            "pathfinder.is_calculating: {}",
172            pathfinder.is_calculating
173        ));
174
175        let executing_path = source.bot.get_component::<ExecutingPath>();
176        let Some(executing_path) = executing_path else {
177            source.reply("I'm not executing a path");
178            return 1;
179        };
180        source.reply(format!(
181            "is_path_partial: {}, path.len: {}, queued_path.len: {}",
182            executing_path.is_path_partial,
183            executing_path.path.len(),
184            if let Some(queued) = executing_path.queued_path {
185                queued.len().to_string()
186            } else {
187                "n/a".to_owned()
188            },
189        ));
190        1
191    }));
192
193    commands.register(literal("startuseitem").executes(|ctx: &Ctx| {
194        let source = ctx.source.lock();
195        source.bot.start_use_item();
196        source.reply("Ok!");
197        1
198    }));
199    commands.register(literal("maxstacksize").executes(|ctx: &Ctx| {
200        let source = ctx.source.lock();
201        let max_stack_size = source
202            .bot
203            .get_held_item()
204            .get_component::<MaxStackSize>()
205            .map_or(-1, |s| s.count);
206        source.reply(format!("{max_stack_size}"));
207        1
208    }));
209
210    commands.register(literal("dimensions").executes(|ctx: &Ctx| {
211        let source = ctx.source.lock();
212        let bot_dimensions = source.bot.dimensions();
213        source.reply(format!("{bot_dimensions:?}"));
214        1
215    }));
216
217    commands.register(literal("players").executes(|ctx: &Ctx| {
218        let source = ctx.source.lock();
219        let player_entities = source
220            .bot
221            .nearest_entities_by::<(), With<metadata::Player>>(|_: ()| true);
222        let tab_list = source.bot.tab_list();
223        for player_entity in player_entities {
224            let uuid = source.bot.entity_component::<EntityUuid>(player_entity);
225            source.reply(format!(
226                "{} - {} ({:?})",
227                player_entity,
228                tab_list.get(&uuid).map_or("?", |p| p.profile.name.as_str()),
229                uuid
230            ));
231        }
232        1
233    }));
234
235    commands.register(literal("enchants").executes(|ctx: &Ctx| {
236        let source = ctx.source.lock();
237        source.bot.with_registry_holder(|r| {
238            let enchants = &r.enchantment;
239            println!("enchants: {enchants:?}");
240        });
241        1
242    }));
243
244    commands.register(literal("attributes").executes(|ctx: &Ctx| {
245        let source = ctx.source.lock();
246        let attributes = source.bot.component::<Attributes>();
247        println!("attributes: {attributes:?}");
248        1
249    }));
250
251    commands.register(literal("debugecsleak").executes(|ctx: &Ctx| {
252        let source = ctx.source.lock();
253
254        source.reply("Ok!");
255
256
257
258        source.bot.disconnect();
259
260        let ecs = source.bot.ecs.clone();
261        thread::spawn(move || {
262            thread::sleep(Duration::from_secs(1));
263            // dump the ecs
264
265            let mut ecs = ecs.lock();
266
267
268
269            let report_path = env::temp_dir().join("azalea-ecs-leak-report.txt");
270            let mut report = File::create(&report_path).unwrap();
271
272            let mut query = ecs.query::<EntityRef>();
273            for entity in query.iter(& ecs) {
274                writeln!(report, "Entity: {}", entity.id()).unwrap();
275                let archetype = entity.archetype();
276                let component_count = archetype.component_count();
277
278                let component_names = archetype
279                    .components()
280                    .iter()
281                    .map(|c| ecs.components().get_info(*c).unwrap().name().to_string())
282                    .collect::<Vec<_>>();
283                writeln!(
284                    report,
285                    "- {component_count} components: {}",
286                    component_names.join(", ")
287                )
288                .unwrap();
289            }
290
291            writeln!(report).unwrap();
292
293
294            for (info, _) in ecs.iter_resources() {
295                let name = info.name().to_string();
296                writeln!(report, "Resource: {name}").unwrap();
297                // writeln!(report, "- Size: {} bytes",
298                // info.layout().size()).unwrap();
299
300                match name.as_ref() {
301                    "azalea_world::container::InstanceContainer" => {
302                        let instance_container = ecs.resource::<InstanceContainer>();
303
304                        for (instance_name, instance) in &instance_container.instances {
305                            writeln!(report, "- Name: {instance_name}").unwrap();
306                            writeln!(report, "- Reference count: {}", instance.strong_count())
307                                .unwrap();
308                            if let Some(instance) = instance.upgrade() {
309                                let instance = instance.read();
310                                let strong_chunks = instance
311                                    .chunks
312                                    .map
313                                    .iter()
314                                    .filter(|(_, v)| v.strong_count() > 0)
315                                    .count();
316                                writeln!(
317                                    report,
318                                    "- Chunks: {} strongly referenced, {} in map",
319                                    strong_chunks,
320                                    instance.chunks.map.len()
321                                )
322                                .unwrap();
323                                writeln!(
324                                    report,
325                                    "- Entities: {}",
326                                    instance.entities_by_chunk.len()
327                                )
328                                .unwrap();
329                            }
330                        }
331                    }
332                    "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
333                        let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
334                        writeln!(report, "- Event count: {}", events.len()).unwrap();
335                    }
336                    "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
337                        let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
338                        writeln!(report, "- Event count: {}", events.len()).unwrap();
339                    }
340
341                    _ => {}
342                }
343            }
344
345            println!("\x1b[1mWrote report to {}\x1b[m", report_path.display());
346        });
347
348        1
349    }));
350
351    commands.register(literal("exit").executes(|ctx: &Ctx| {
352        let source = ctx.source.lock();
353        source.reply("bye!");
354
355        source.bot.disconnect();
356
357        let source = ctx.source.clone();
358        thread::spawn(move || {
359            thread::sleep(Duration::from_secs(1));
360
361            source.lock().bot.ecs.lock().write_message(AppExit::Success);
362        });
363
364        1
365    }));
366}
Source

pub fn x_rot(&self) -> f32

Returns pitch (up and down) in degrees.

Clamped to ±90°.

Examples found in repository?
azalea/examples/testbot/commands/debug.rs (line 96)
26pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
27    commands.register(literal("ping").executes(|ctx: &Ctx| {
28        let source = ctx.source.lock();
29        source.reply("pong!");
30        1
31    }));
32
33    commands.register(literal("disconnect").executes(|ctx: &Ctx| {
34        let source = ctx.source.lock();
35        source.bot.disconnect();
36        1
37    }));
38
39    commands.register(literal("whereami").executes(|ctx: &Ctx| {
40        let mut source = ctx.source.lock();
41        let Some(entity) = source.entity() else {
42            source.reply("You aren't in render distance!");
43            return 0;
44        };
45        let position = source.bot.entity_component::<Position>(entity);
46        source.reply(format!(
47            "You are at {}, {}, {}",
48            position.x, position.y, position.z
49        ));
50        1
51    }));
52
53    commands.register(literal("entityid").executes(|ctx: &Ctx| {
54        let mut source = ctx.source.lock();
55        let Some(entity) = source.entity() else {
56            source.reply("You aren't in render distance!");
57            return 0;
58        };
59        let entity_id = source.bot.entity_component::<MinecraftEntityId>(entity);
60        source.reply(format!(
61            "Your Minecraft ID is {} and your ECS ID is {entity:?}",
62            *entity_id
63        ));
64        1
65    }));
66
67    let whereareyou = |ctx: &Ctx| {
68        let source = ctx.source.lock();
69        let position = source.bot.position();
70        source.reply(format!(
71            "I'm at {}, {}, {}",
72            position.x, position.y, position.z
73        ));
74        1
75    };
76    commands.register(literal("whereareyou").executes(whereareyou));
77    commands.register(literal("pos").executes(whereareyou));
78
79    commands.register(literal("whoareyou").executes(|ctx: &Ctx| {
80        let source = ctx.source.lock();
81        source.reply(format!(
82            "I am {} ({}, {})",
83            source.bot.username(),
84            source.bot.uuid(),
85            source.bot.entity
86        ));
87        1
88    }));
89
90    commands.register(literal("getdirection").executes(|ctx: &Ctx| {
91        let source = ctx.source.lock();
92        let direction = source.bot.component::<LookDirection>();
93        source.reply(format!(
94            "I'm looking at {}, {}",
95            direction.y_rot(),
96            direction.x_rot()
97        ));
98        1
99    }));
100
101    commands.register(literal("health").executes(|ctx: &Ctx| {
102        let source = ctx.source.lock();
103
104        let health = source.bot.health();
105        source.reply(format!("I have {health} health"));
106        1
107    }));
108
109    commands.register(literal("lookingat").executes(|ctx: &Ctx| {
110        let source = ctx.source.lock();
111
112        let hit_result = source.bot.component::<HitResultComponent>();
113
114        match &*hit_result {
115            HitResult::Block(r) => {
116                if r.miss {
117                    source.reply("I'm not looking at anything");
118                    return 0;
119                }
120                let block_pos = r.block_pos;
121                let block = source.bot.world().read().get_block_state(block_pos);
122                source.reply(format!("I'm looking at {block:?} at {block_pos:?}"));
123            }
124            HitResult::Entity(r) => {
125                let entity_kind = *source.bot.entity_component::<EntityKindComponent>(r.entity);
126                source.reply(format!(
127                    "I'm looking at {entity_kind} ({:?}) at {}",
128                    r.entity, r.location
129                ));
130            }
131        }
132
133        1
134    }));
135
136    commands.register(literal("getblock").then(argument("x", integer()).then(
137        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
138            let source = ctx.source.lock();
139            let x = get_integer(ctx, "x").unwrap();
140            let y = get_integer(ctx, "y").unwrap();
141            let z = get_integer(ctx, "z").unwrap();
142            println!("getblock xyz {x} {y} {z}");
143            let block_pos = BlockPos::new(x, y, z);
144            let block = source.bot.world().read().get_block_state(block_pos);
145            source.reply(format!("BlockKind at {block_pos} is {block:?}"));
146            1
147        })),
148    )));
149    commands.register(literal("getfluid").then(argument("x", integer()).then(
150        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
151            let source = ctx.source.lock();
152            let x = get_integer(ctx, "x").unwrap();
153            let y = get_integer(ctx, "y").unwrap();
154            let z = get_integer(ctx, "z").unwrap();
155            println!("getfluid xyz {x} {y} {z}");
156            let block_pos = BlockPos::new(x, y, z);
157            let block = source.bot.world().read().get_fluid_state(block_pos);
158            source.reply(format!("Fluid at {block_pos} is {block:?}"));
159            1
160        })),
161    )));
162
163    commands.register(literal("pathfinderstate").executes(|ctx: &Ctx| {
164        let source = ctx.source.lock();
165        let pathfinder = source.bot.get_component::<Pathfinder>();
166        let Some(pathfinder) = pathfinder else {
167            source.reply("I don't have the Pathfinder ocmponent");
168            return 1;
169        };
170        source.reply(format!(
171            "pathfinder.is_calculating: {}",
172            pathfinder.is_calculating
173        ));
174
175        let executing_path = source.bot.get_component::<ExecutingPath>();
176        let Some(executing_path) = executing_path else {
177            source.reply("I'm not executing a path");
178            return 1;
179        };
180        source.reply(format!(
181            "is_path_partial: {}, path.len: {}, queued_path.len: {}",
182            executing_path.is_path_partial,
183            executing_path.path.len(),
184            if let Some(queued) = executing_path.queued_path {
185                queued.len().to_string()
186            } else {
187                "n/a".to_owned()
188            },
189        ));
190        1
191    }));
192
193    commands.register(literal("startuseitem").executes(|ctx: &Ctx| {
194        let source = ctx.source.lock();
195        source.bot.start_use_item();
196        source.reply("Ok!");
197        1
198    }));
199    commands.register(literal("maxstacksize").executes(|ctx: &Ctx| {
200        let source = ctx.source.lock();
201        let max_stack_size = source
202            .bot
203            .get_held_item()
204            .get_component::<MaxStackSize>()
205            .map_or(-1, |s| s.count);
206        source.reply(format!("{max_stack_size}"));
207        1
208    }));
209
210    commands.register(literal("dimensions").executes(|ctx: &Ctx| {
211        let source = ctx.source.lock();
212        let bot_dimensions = source.bot.dimensions();
213        source.reply(format!("{bot_dimensions:?}"));
214        1
215    }));
216
217    commands.register(literal("players").executes(|ctx: &Ctx| {
218        let source = ctx.source.lock();
219        let player_entities = source
220            .bot
221            .nearest_entities_by::<(), With<metadata::Player>>(|_: ()| true);
222        let tab_list = source.bot.tab_list();
223        for player_entity in player_entities {
224            let uuid = source.bot.entity_component::<EntityUuid>(player_entity);
225            source.reply(format!(
226                "{} - {} ({:?})",
227                player_entity,
228                tab_list.get(&uuid).map_or("?", |p| p.profile.name.as_str()),
229                uuid
230            ));
231        }
232        1
233    }));
234
235    commands.register(literal("enchants").executes(|ctx: &Ctx| {
236        let source = ctx.source.lock();
237        source.bot.with_registry_holder(|r| {
238            let enchants = &r.enchantment;
239            println!("enchants: {enchants:?}");
240        });
241        1
242    }));
243
244    commands.register(literal("attributes").executes(|ctx: &Ctx| {
245        let source = ctx.source.lock();
246        let attributes = source.bot.component::<Attributes>();
247        println!("attributes: {attributes:?}");
248        1
249    }));
250
251    commands.register(literal("debugecsleak").executes(|ctx: &Ctx| {
252        let source = ctx.source.lock();
253
254        source.reply("Ok!");
255
256
257
258        source.bot.disconnect();
259
260        let ecs = source.bot.ecs.clone();
261        thread::spawn(move || {
262            thread::sleep(Duration::from_secs(1));
263            // dump the ecs
264
265            let mut ecs = ecs.lock();
266
267
268
269            let report_path = env::temp_dir().join("azalea-ecs-leak-report.txt");
270            let mut report = File::create(&report_path).unwrap();
271
272            let mut query = ecs.query::<EntityRef>();
273            for entity in query.iter(& ecs) {
274                writeln!(report, "Entity: {}", entity.id()).unwrap();
275                let archetype = entity.archetype();
276                let component_count = archetype.component_count();
277
278                let component_names = archetype
279                    .components()
280                    .iter()
281                    .map(|c| ecs.components().get_info(*c).unwrap().name().to_string())
282                    .collect::<Vec<_>>();
283                writeln!(
284                    report,
285                    "- {component_count} components: {}",
286                    component_names.join(", ")
287                )
288                .unwrap();
289            }
290
291            writeln!(report).unwrap();
292
293
294            for (info, _) in ecs.iter_resources() {
295                let name = info.name().to_string();
296                writeln!(report, "Resource: {name}").unwrap();
297                // writeln!(report, "- Size: {} bytes",
298                // info.layout().size()).unwrap();
299
300                match name.as_ref() {
301                    "azalea_world::container::InstanceContainer" => {
302                        let instance_container = ecs.resource::<InstanceContainer>();
303
304                        for (instance_name, instance) in &instance_container.instances {
305                            writeln!(report, "- Name: {instance_name}").unwrap();
306                            writeln!(report, "- Reference count: {}", instance.strong_count())
307                                .unwrap();
308                            if let Some(instance) = instance.upgrade() {
309                                let instance = instance.read();
310                                let strong_chunks = instance
311                                    .chunks
312                                    .map
313                                    .iter()
314                                    .filter(|(_, v)| v.strong_count() > 0)
315                                    .count();
316                                writeln!(
317                                    report,
318                                    "- Chunks: {} strongly referenced, {} in map",
319                                    strong_chunks,
320                                    instance.chunks.map.len()
321                                )
322                                .unwrap();
323                                writeln!(
324                                    report,
325                                    "- Entities: {}",
326                                    instance.entities_by_chunk.len()
327                                )
328                                .unwrap();
329                            }
330                        }
331                    }
332                    "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
333                        let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
334                        writeln!(report, "- Event count: {}", events.len()).unwrap();
335                    }
336                    "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
337                        let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
338                        writeln!(report, "- Event count: {}", events.len()).unwrap();
339                    }
340
341                    _ => {}
342                }
343            }
344
345            println!("\x1b[1mWrote report to {}\x1b[m", report_path.display());
346        });
347
348        1
349    }));
350
351    commands.register(literal("exit").executes(|ctx: &Ctx| {
352        let source = ctx.source.lock();
353        source.reply("bye!");
354
355        source.bot.disconnect();
356
357        let source = ctx.source.clone();
358        thread::spawn(move || {
359            thread::sleep(Duration::from_secs(1));
360
361            source.lock().bot.ecs.lock().write_message(AppExit::Success);
362        });
363
364        1
365    }));
366}
Source

pub fn update(&mut self, new: LookDirection)

Update this look direction to the new value.

This handles relative rotations correctly and with the default Minecraft sensitivity to avoid triggering anticheats.

Source

pub fn update_y_rot(&mut self, new_y_rot: f32)

Update the y_rot to the given value, in degrees.

This is a shortcut for Self::update while keeping the x_rot the same.

Source

pub fn update_x_rot(&mut self, new_x_rot: f32)

Update the x_rot to the given value, in degrees.

This is a shortcut for Self::update while keeping the y_rot the same.

Source

pub fn update_with_sensitivity(&mut self, new: LookDirection, sensitivity: f32)

Update this look direction to the new value, using the given sensitivity value.

Consider using Self::update instead, which uses 1.0 as the sensitivity (equivalent to 100% sensitivity in Minecraft).

Trait Implementations§

Source§

impl AzaleaRead for LookDirection

Source§

fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError>

Source§

impl AzaleaWrite for LookDirection

Source§

fn azalea_write(&self, buf: &mut impl Write) -> Result<(), Error>

Source§

impl Clone for LookDirection

Source§

fn clone(&self) -> LookDirection

Returns a duplicate of the value. Read more
1.0.0§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Component for LookDirection
where Self: Send + Sync + 'static,

Source§

const STORAGE_TYPE: StorageType = bevy_ecs::component::StorageType::Table

A constant indicating the storage type used for this component.
Source§

type Mutability = Mutable

A marker type to assist Bevy with determining if this component is mutable, or immutable. Mutable components will have [Component<Mutability = Mutable>], while immutable components will instead have [Component<Mutability = Immutable>]. Read more
Source§

fn register_required_components( _requiree: ComponentId, required_components: &mut RequiredComponentsRegistrator<'_, '_>, )

Registers required components. Read more
Source§

fn clone_behavior() -> ComponentCloneBehavior

Called when registering this component, allowing to override clone function (or disable cloning altogether) for this component. Read more
§

fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_add [ComponentHook] for this [Component] if one is defined.
§

fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_insert [ComponentHook] for this [Component] if one is defined.
§

fn on_replace() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_replace [ComponentHook] for this [Component] if one is defined.
§

fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_remove [ComponentHook] for this [Component] if one is defined.
§

fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_despawn [ComponentHook] for this [Component] if one is defined.
§

fn map_entities<E>(_this: &mut Self, _mapper: &mut E)
where E: EntityMapper,

Maps the entities on this component using the given [EntityMapper]. This is used to remap entities in contexts like scenes and entity cloning. When deriving [Component], this is populated by annotating fields containing entities with #[entities] Read more
Source§

impl Debug for LookDirection

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for LookDirection

Source§

fn default() -> LookDirection

Returns the “default value” for a type. Read more
Source§

impl From<(f32, f32)> for LookDirection

Source§

fn from((y_rot, x_rot): (f32, f32)) -> Self

Converts to this type from the input type.
Source§

impl From<LookDirection> for (f32, f32)

Source§

fn from(value: LookDirection) -> Self

Converts to this type from the input type.
Source§

impl Hash for LookDirection

Source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for LookDirection

Source§

fn eq(&self, other: &LookDirection) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for LookDirection

Source§

impl Eq for LookDirection

Source§

impl StructuralPartialEq for LookDirection

Auto Trait Implementations§

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<C> Bundle for C
where C: Component,

§

fn component_ids( components: &mut ComponentsRegistrator<'_>, ids: &mut impl FnMut(ComponentId), )

§

fn get_component_ids( components: &Components, ids: &mut impl FnMut(Option<ComponentId>), )

Gets this [Bundle]’s component ids. This will be None if the component has not been registered.
§

impl<C> BundleFromComponents for C
where C: Component,

§

unsafe fn from_components<T, F>(ctx: &mut T, func: &mut F) -> C
where F: for<'a> FnMut(&'a mut T) -> OwningPtr<'a>,

§

impl<T> CloneToUninit for T
where T: Clone,

§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSend for T
where T: Any + Send,

§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

impl<T> DynEq for T
where T: Any + Eq,

§

fn dyn_eq(&self, other: &(dyn DynEq + 'static)) -> bool

This method tests for self and other values to be equal. Read more
§

impl<T> DynHash for T
where T: DynEq + Hash,

§

fn dyn_hash(&self, state: &mut dyn Hasher)

Feeds this value into the given Hasher.
§

impl<C> DynamicBundle for C
where C: Component,

§

type Effect = ()

An operation on the entity that happens after inserting this bundle.
§

unsafe fn get_components( ptr: MovingPtr<'_, C>, func: &mut impl FnMut(StorageType, OwningPtr<'_>), ) -> <C as DynamicBundle>::Effect

Moves the components out of the bundle. Read more
§

unsafe fn apply_effect( _ptr: MovingPtr<'_, MaybeUninit<C>>, _entity: &mut EntityWorldMut<'_>, )

Applies the after-effects of spawning this bundle. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromWorld for T
where T: Default,

§

fn from_world(_world: &mut World) -> T

Creates Self using default().

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> IntoResult<T> for T

§

fn into_result(self) -> Result<T, RunSystemError>

Converts this type into the system output type.
§

impl<A> Is for A
where A: Any,

§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

§

fn clone_type_data(&self) -> Box<dyn TypeData>

Creates a type-erased clone of this value.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ConditionalSend for T
where T: Send,