-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add_edges
and add_grid
helpers for DirectionalNavMap
#17247
base: main
Are you sure you want to change the base?
Conversation
add_edges
and add_grid helpers for
DirectionalNavMap`add_edges
and add_grid
helpers for DirectionalNavMap
Co-authored-by: IQuick 143 <[email protected]>
// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple positions for the same node would make this very tricky/not possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: This collision can happen also by just an entity looping to itself, which may or (probably) may not be desired.
@@ -114,6 +137,18 @@ pub enum CompassOctant { | |||
} | |||
|
|||
impl CompassOctant { | |||
/// The list of all possible [`CompassOctant`] variants. | |||
pub const VARIANTS: [CompassOctant; 8] = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 :)
Objective
Prompted by #17224, I realized that we need more helpers to make configuring
DirectionalNavMap
s for directional (gamepad) navigation easier.Solution
add_edges
helper, which does not loop around the end of the list.add_grid
helper 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