bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
33.48k stars 3.26k forks source link

UI Node's dimensions are incorrectly calculated if camera at first node's update had zero size #13600

Open bugsweeper opened 1 month ago

bugsweeper commented 1 month ago

why that would stick rather than get updated here

The reason is that compute_camera_layout() updates resolution in root_nodes.implicit_viewport_node which containes node for viewport (this is correct, because available_space relates to viewport), but then update_uinode_geometry_recursive() updates geometry starting from user ui root node which is just a child of viewport node. So user ui root node doesn't update according to updated camera.size.

Originally posted by @bugsweeper in https://github.com/bevyengine/bevy/issues/13517#issuecomment-2139359533

bugsweeper commented 1 month ago

Behaviour is rare (app launched ~30 times to reproduce) image

bugsweeper commented 4 weeks ago

I was wrong about source of problem earlier. compute_camera_layout() generates layout for viewport and all of it's child into cache (for current resolution). Then update_uinode_geometry_recursive() places nodes according to layout from cache. The reason of #13517 is that layout is generated from styles (taffy's version of it) of node, but taffy's version of style of root node allready contains width equals to Some(0.0)! Why? Because first time camera resolution was (0.0, 0.0), this is why when UiSurface::upsert_node it converts from bevy's style to taffy's style once, and never changes. It sets width to 0.0 because of Val::Vw(100.0) for zero resolution gives just 0.0. I don't see nice solution yet. @nicoburns Can you, as the author of layout calculation, advise what is best? Clear fields in taffy's Style which corresponds to Val fields in bevy's Style or just convert styles again before layout calculation?

bugsweeper commented 4 weeks ago

Before you ask, UiSurface doesn't upsert again, because no condition is met, because when camera changes resolution from zero to nonzero it doesn't understand that something changes, it assumes that camera changes resolution when window changes resolution, attaching is not the case

bugsweeper commented 4 weeks ago

@porkbrain Looks like you can workaround by emmiting resize event for window containing your ui after respawn of ui and camera