-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Overrides for no-path in autonavigation for bevy_input_focus
#22634
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
base: main
Are you sure you want to change the base?
Overrides for no-path in autonavigation for bevy_input_focus
#22634
Conversation
Changes navigation to use a 3-state enum, distinguishing between "unset" neighbors, "explicitly removed" neighbors, and "known" neighbors. Unset neighbors can be overwritten by auto nav building, while explicitly removed slots cannot.
Documents surprising behavior when inputting a diagonal direction (ie. `NorthWest`) when one of the components are blocked (ie. `North`)
| pub enum NavNeighbor { | ||
| /// No neighbor explicitly set. | ||
| #[default] | ||
| Unset, |
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.
Doesn't this mean that it will be left to be determined automatically, so maybe Auto would be clearer?
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.
Renamed to Auto in latest commit.
| /// Do not find a neighbor. | ||
| Blocked, | ||
| /// The neighbor is known and set. | ||
| Neighbor(Entity), |
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.
NavNeighbor::Neighbor seems a bit redundant, maybe NavNeighbor::Set(Entity)?
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.
Renamed to Set in latest commit.
| .set(direction, b); | ||
| } | ||
|
|
||
| /// Adds an edge blocking automatic naviation from an entity in a direction. |
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.
| /// Adds an edge blocking automatic naviation from an entity in a direction. | |
| /// Adds an edge blocking automatic navigation from an entity in a direction. |
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.
Thanks for catching that, fixed typo in latest commit.
kfc35
left a comment
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.
Overall, this looks great. I just have small wording fixes / nits. Thank you for your work!
| /// Adds an edge blocking automatic navigation from an entity in a direction. | ||
| /// Any existing edge from A in the provided direction will be overwritten. | ||
| /// | ||
| /// The reverse block will not be added, so navigation will only be possible from other entities |
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 sentence sounds a little unclear
| /// The reverse block will not be added, so navigation will only be possible from other entities | |
| /// The reverse block will not be added, so navigation will still be possible from other entities | |
| /// to the provided entity in the [`CompassOctant::opposite`] direction |
| self.add_edge(b, a, direction.opposite()); | ||
| } | ||
|
|
||
| // TODO: not quite sure if this is necessary |
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.
I think this is OK to provide; it is small enough to include
| } | ||
|
|
||
| // TODO: not quite sure if this is necessary | ||
| /// Adds a symmetrical edge between two entities in the navigation map. |
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.
| /// Adds a symmetrical edge between two entities in the navigation map. | |
| /// Adds a symmetrical blocking edge between two entities in the navigation map. |
|
|
||
| // TODO: not quite sure if this is necessary | ||
| /// Adds a symmetrical edge between two entities in the navigation map. | ||
| /// The A -> B path will use the provided direction, while B -> A will use the [`CompassOctant::opposite`] variant. |
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.
| /// The A -> B path will use the provided direction, while B -> A will use the [`CompassOctant::opposite`] variant. | |
| /// The blocking A -> B path will use the provided direction, while B -> A will use the [`CompassOctant::opposite`] variant. |
| /// | ||
| /// If the entity is not in the map, [`None`] will be returned. | ||
| /// Note that the set of neighbors is not guaranteed to be non-empty though! | ||
| /// Note that the set of neighbors may be the default value! |
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.
By “default value” do you mean the EMPTY value?
| direction: CompassOctant, | ||
| }, | ||
| /// Navigation explicitly blocked in the requested direction. | ||
| #[error("Naviation explicitly blocked from {current_focus} in the {direction:?} direction.")] |
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.
| #[error("Naviation explicitly blocked from {current_focus} in the {direction:?} direction.")] | |
| #[error("Navigation explicitly blocked from {current_focus} in the {direction:?} direction.")] |
| pages_entities[1][3], | ||
| CompassOctant::SouthEast, | ||
| ); | ||
| // Add one-way blocking within the triangle page (Page 1) for down nav. |
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.
| // Add one-way blocking within the triangle page (Page 1) for down nav. | |
| // Add one-way blocking within the first grid page (Page 1) for down nav. |
| .id(); | ||
| text_entities.push(footer_info); | ||
| } | ||
| if page_num == 0 { |
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.
nit: instead of copying the if block, you can just have a variable that the Text is set to that is switched based on page_num i.e. something like (excuse the formatting)
let text = if page_num == 2 {
"Vertical Navigation has been manually overridden to be inverted! \ ^ moves down, and v (down) moves up.”, } else {
"Vertical movements disabled on each button, but you can still go to the next row by going off the right side.”
}
|
|
||
| // Manually set a block from A to B | ||
| // A should NOT be able to nav East to B | ||
| // but SHOULD be able to nav South to C |
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.
can you add an assert for this? it seems like there should be an assert by the way this comment is written, but it isn’t right now
Objective
bevy_input_focus: Ability to manually set “no navigation in a given direction” for an entity #22378 .Solution
Turn
NavNeighborsfrom storing an array ofOption<Entity>to an array ofNavNeighbor, an enum with 3 values:Unset(no explicitly set thing in this direction),Blocked(assume there is nothing in this direction to path to), andNeighbor(Entity).Testing
Changes tested using a new test,
test_respects_set_blocks, and manually using thedirectional_navigation_overrideexample. Each button on second page is restricted to left/right movement, as up/down are blocked.Showcase
I'm not quite sure how to showcase this, as it's a very input-oriented feature and the feature working means that nothing happens.