add_edges and add_grid helpers for DirectionalNavMap#17247
add_edges and add_grid helpers for DirectionalNavMap#17247alice-i-cecile wants to merge 14 commits intobevyengine:mainfrom
add_edges and add_grid helpers for DirectionalNavMap#17247Conversation
add_edges and add_grid helpers for DirectionalNavMap`add_edges and add_grid helpers for DirectionalNavMap
Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
| // which uses u16 values. We need signed integers here, but we should be able to cast them losslessly. | ||
| // PERF: This is a very flexible / "clever" implementation, but it won't be the fastest for simple cases. | ||
| // If there's user demand for it, we can add a more optimized / less flexible version that requires non-sparse rectangular grids. | ||
| pub fn add_grid(&mut self, entity_grid: NavGrid, should_loop: bool) { |
There was a problem hiding this comment.
This promises support for placing entities at multiple locations, however it's not well defined what the result is.
Consider the following grid:
X A
Y A
Now... what is the left neighbour of A? It seems to be completely implementation dependent.
There was a problem hiding this comment.
Yeah, we should probably choose, document and test a rule for this.
| // Inserting the same entity at multiple locations is supported, | ||
| // so we need to check for this case | ||
| if neighbor != entity { | ||
| // PERF: we could also add the reverse edge here, to save work later |
There was a problem hiding this comment.
Multiple positions for the same node would make this very tricky/not possible.
There was a problem hiding this comment.
Right 🤔 Okay, I'll cut the PERF note.
|
|
||
| if let Some(neighbor) = maybe_neighbor { | ||
| // Entities should not be neighbors of themselves | ||
| // Inserting the same entity at multiple locations is supported, |
There was a problem hiding this comment.
Note: This collision can happen also by just an entity looping to itself, which may or (probably) may not be desired.
|
|
||
| impl CompassOctant { | ||
| /// The list of all possible [`CompassOctant`] variants. | ||
| pub const VARIANTS: [CompassOctant; 8] = [ |
There was a problem hiding this comment.
Might be nice to test that this is in the same order as from_index (could we implement from_index like that?)
| @@ -21,9 +21,11 @@ use bevy_ecs::{ | |||
| prelude::*, | |||
There was a problem hiding this comment.
As a general thought, I think my ideal system is an automatic system that is overridden by manually defined nav targets.
Ex: label ui nodes as "navigable", then for each "navigable" node, compute the closest/best-fit navigable node in the direction specified, unless a node for that direction has been manually specified.
Forcing users to define the graph up front is too cumbersome for the majority of use cases. Ex: a flat list of navigable nodes is trivially implicitly navigable.
There was a problem hiding this comment.
This is especially important because many lists of nodes will have different targets based on their current layout. We essentially need those cases to automatically/implicitly adapt to the current context.
There was a problem hiding this comment.
As a general thought, I think my ideal system is an automatic system that is overridden by manually defined nav targets.
Fully agree here! I've been exploring APIs and algorithms to make this possible :)
|
I think this design of add_grid is a bit too complex / fraught for now. I may revisit it if we want to come back to this later. |
# Objective While `add_looping_edges` is a helpful method for manually defining directional navigation maps, we don't always want to loop around! ## Solution Add a non-looping variant. These commits are cherrypicked from the more complex #17247. ## Testing I've updated the `directional_navigation` example to use these changes, and verified that it works. --------- Co-authored-by: Rob Parrett <robparrett@gmail.com> Co-authored-by: Benjamin Brienen <benjamin.brienen@outlook.com>
# Objective While `add_looping_edges` is a helpful method for manually defining directional navigation maps, we don't always want to loop around! ## Solution Add a non-looping variant. These commits are cherrypicked from the more complex bevyengine#17247. ## Testing I've updated the `directional_navigation` example to use these changes, and verified that it works. --------- Co-authored-by: Rob Parrett <robparrett@gmail.com> Co-authored-by: Benjamin Brienen <benjamin.brienen@outlook.com>
# Context Renaming `Parent` to `ChildOf` in #17247 has been contentious. While those users concerns are valid (especially around legibility of code IMO!), @cart [has decided](https://discord.com/channels/691052431525675048/749335865876021248/1340434322833932430) to stick with the new name. > In general this conversation is unsurprising to me, as it played out essentially the same way when I asked for opinions in my PR. There are strong opinions on both sides. Everyone is right in their own way. > > I chose ChildOf for the following reasons: > > 1. I think it derives naturally from the system we have built, the concepts we have chosen, and how we generally name the types that implement a trait in Rust. This is the name of the type implementing Relationship. We are adding that Relationship component to a given entity (whether it "is" the relationship or "has" the relationship is kind of immaterial ... we are naming the relationship that it "is" or "has"). What is the name of the relationship that a child has to its parent? It is a "child" of the parent of course! > 2. In general the non-parent/child relationships I've seen in the wild generally benefit from (or need to) use the naming convention in (1) (aka calling the Relationship the name of the relationship the entity has). Many relationships don't have an equivalent to the Parent/Child name concept. > 3. I do think we could get away with using (1) for pretty much everything else and special casing Parent/Children. But by embracing the naming convention, we help establish that this is in fact a pattern, and we help prime people to think about these things in a consistent way. Consistency and predictability is a generally desirable property. And for something as divisive and polarizing as relationship naming, I think drawing a hard line in the sand is to the benefit of the community as a whole. > 4. I believe the fact that we dont see as much of the XOf naming style elsewhere is to our benefit. When people see things in that style, they are primed to think of them as relationships (after some exposure to Bevy and the ecosystem). I consider this a useful hint. > 5. Most of the practical confusion from using ChildOf seems to be from calling the value of the target field we read from the relationship child_of. The name of the target field should be parent (we could even consider renaming child_of.0 to child_of.parent for clarity). I suspect that existing Bevy users renaming their existing code will feel the most friction here, as this requires a reframing. Imo it is natural and expected to receive pushback from these users hitting this case. ## Objective The new documentation doesn't do a particularly good job at quickly explaining the meaning of each component or how to work with them; making a tricky migration more painful and slowing down new users as they learn about some of the most fundamental types in Bevy. ## Solution 1. Clearly explain what each component does in the very first line, assuming no background knowledge. This is the first relationships that 99% of users will encounter, so explaining that they are relationships is unhelpful as an introduction. 2. Add doc aliases for the rejected `IsParent`/`IsChild`/`Parent` names, to improve autocomplete and doc searching. 3. Do some assorted docs cleanup while we're here. --------- Co-authored-by: Eagster <79881080+ElliottjPierce@users.noreply.github.com>
Objective
Prompted by #17224, I realized that we need more helpers to make configuring
DirectionalNavMaps for directional (gamepad) navigation easier.Solution
add_edgeshelper, which does not loop around the end of the list.add_gridhelper for working with grids.Testing
I'm currently relying on unit tests for these changes. Once #17224 is merged, we can update that the example to test these in a more hands-on way.
To do