initial
This commit is contained in:
commit
bbbf24fd2d
6 changed files with 6062 additions and 0 deletions
11
.cargo/config.toml
Normal file
11
.cargo/config.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
[unstable]
|
||||||
|
codegen-backend = true
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
codegen-backend = "cranelift"
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
codegen-backend = "llvm"
|
||||||
|
|
||||||
|
[target.x86_64-unknown-linux-gnu]
|
||||||
|
rustflags = [ "-Zshare-generics=y" ]
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
5717
Cargo.lock
generated
Normal file
5717
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
24
Cargo.toml
Normal file
24
Cargo.toml
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
[package]
|
||||||
|
name = "bevy_scene_switch"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bevy = { version = "0.18.0", features = ["debug", "dynamic_linking", "experimental_bevy_ui_widgets", "wayland"] }
|
||||||
|
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 1
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
opt-level = 3
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
codegen-units = 1
|
||||||
|
lto = "thin"
|
||||||
|
|
||||||
|
[target.x86_64-unknown-linux-gnu]
|
||||||
|
linker = "clang"
|
||||||
|
rustflags = ["-C", "link-arg=-fuse-ld=/usr/bin/mold"]
|
||||||
BIN
assets/fonts/default.ttf
Normal file
BIN
assets/fonts/default.ttf
Normal file
Binary file not shown.
309
src/main.rs
Normal file
309
src/main.rs
Normal file
|
|
@ -0,0 +1,309 @@
|
||||||
|
use bevy::{
|
||||||
|
color::palettes::css::WHITE,
|
||||||
|
input::common_conditions::input_just_released,
|
||||||
|
input_focus::InputDispatchPlugin, picking::hover::Hovered,
|
||||||
|
prelude::*,
|
||||||
|
reflect::Is,
|
||||||
|
sprite::Anchor, ui::{
|
||||||
|
InteractionDisabled,
|
||||||
|
Pressed,
|
||||||
|
}, ui_widgets::{
|
||||||
|
Activate,
|
||||||
|
Button,
|
||||||
|
UiWidgetsPlugins,
|
||||||
|
observe,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Menu;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct TwoD;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct ThreeD;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct MenuButton;
|
||||||
|
|
||||||
|
fn menu_button(asset_server: &AssetServer, width: Val, height: Val, text: impl ToString) -> impl Bundle {
|
||||||
|
(
|
||||||
|
Node {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
border: UiRect::all(px(5)),
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
border_radius: BorderRadius::MAX,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
Button,
|
||||||
|
MenuButton,
|
||||||
|
Hovered::default(),
|
||||||
|
BorderColor::all(Color::BLACK),
|
||||||
|
BackgroundColor(Color::srgb(0.7, 0.7, 0.7)),
|
||||||
|
children![(
|
||||||
|
Text::new(text.to_string()),
|
||||||
|
TextFont {
|
||||||
|
font: asset_server.load("fonts/default.ttf"),
|
||||||
|
font_size: 24.0,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
TextColor(Color::srgb(0.2, 0.2, 0.2)),
|
||||||
|
)],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn button_on_interaction<E: EntityEvent, C: Component>(
|
||||||
|
event: On<E, C>,
|
||||||
|
mut buttons: Query<
|
||||||
|
(
|
||||||
|
&Hovered,
|
||||||
|
Has<InteractionDisabled>,
|
||||||
|
Has<Pressed>,
|
||||||
|
&mut BorderColor,
|
||||||
|
&Children,
|
||||||
|
),
|
||||||
|
With<MenuButton>,
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
if let Ok((hovered, disabled, pressed, mut border_color, children)) =
|
||||||
|
buttons.get_mut(event.event_target())
|
||||||
|
{
|
||||||
|
if children.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let hovered = hovered.get();
|
||||||
|
let pressed = pressed && !(E::is::<Remove>() && C::is::<Pressed>());
|
||||||
|
let disabled = disabled && !(E::is::<Remove>() && C::is::<InteractionDisabled>());
|
||||||
|
match (disabled, hovered, pressed) {
|
||||||
|
// Disabled button
|
||||||
|
(true, _, _) => {
|
||||||
|
border_color.set_all(Color::srgb(0.8, 0.8, 0.8));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pressed and hovered button
|
||||||
|
(false, true, true) => {
|
||||||
|
border_color.set_all(Color::srgb(1.0, 0.3, 0.3));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hovered, unpressed button
|
||||||
|
(false, true, false) => {
|
||||||
|
border_color.set_all(Color::srgb(1.0, 1.0, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unhovered button (either pressed or not).
|
||||||
|
(false, false, _) => {
|
||||||
|
border_color.set_all(Color::srgb(0.0, 0.0, 0.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn handle_escape(
|
||||||
|
mut commands: Commands,
|
||||||
|
maybe_2d: Option<Single<(),With<TwoD>>>,
|
||||||
|
maybe_3d: Option<Single<(),With<ThreeD>>>,
|
||||||
|
) {
|
||||||
|
if maybe_2d.is_some() {
|
||||||
|
commands.run_system_cached(multidim_switch_2d_to_menu);
|
||||||
|
} else if maybe_3d.is_some() {
|
||||||
|
commands.run_system_cached(multidim_switch_3d_to_menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn menu_bundle(asset_server: &AssetServer) -> impl Bundle {
|
||||||
|
(
|
||||||
|
Menu,
|
||||||
|
Node {
|
||||||
|
width: percent(100),
|
||||||
|
height: percent(100),
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
display: Display::Flex,
|
||||||
|
flex_direction: FlexDirection::Column,
|
||||||
|
row_gap: px(10),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
children![
|
||||||
|
( Camera2d ),
|
||||||
|
(
|
||||||
|
menu_button(asset_server, px(160), px(64), "2D"),
|
||||||
|
observe(multidim_switch_menu_to_2d),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
menu_button(asset_server, px(160), px(64), "3D"),
|
||||||
|
observe(multidim_switch_menu_to_3d),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bundle_2d(asset_server: &AssetServer, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<ColorMaterial>>) -> impl Bundle {
|
||||||
|
(
|
||||||
|
TwoD,
|
||||||
|
Transform::default(),
|
||||||
|
children![
|
||||||
|
( Camera2d ),
|
||||||
|
(
|
||||||
|
Mesh2d(meshes.add(Rectangle::default())),
|
||||||
|
MeshMaterial2d(materials.add(Color::from(WHITE))),
|
||||||
|
Anchor::CENTER,
|
||||||
|
Transform {
|
||||||
|
translation: (-1. * Vec3::Z),
|
||||||
|
scale: Vec3::splat(128.),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
Text2d::new("Random text over random mesh".to_string()),
|
||||||
|
TextFont {
|
||||||
|
font: asset_server.load("fonts/default.ttf"),
|
||||||
|
font_size: 24.0,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
Anchor::CENTER,
|
||||||
|
TextBackgroundColor(Color::BLACK),
|
||||||
|
Transform::from_translation(Vec3 { x: 0., y: 100., z: 1. }),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bundle_3d(mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<StandardMaterial>>) -> impl Bundle {
|
||||||
|
(
|
||||||
|
ThreeD,
|
||||||
|
Transform::default(),
|
||||||
|
children![
|
||||||
|
(
|
||||||
|
Mesh3d(meshes.add(Circle::new(4.0))),
|
||||||
|
MeshMaterial3d(materials.add(Color::WHITE)),
|
||||||
|
Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
|
||||||
|
MeshMaterial3d(materials.add(Color::WHITE)),
|
||||||
|
Transform::from_xyz(0., 0.5, 0.),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
PointLight {
|
||||||
|
shadows_enabled: true,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
Transform::from_xyz(4.0, 8.0, 4.0),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
Camera3d::default(),
|
||||||
|
Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn multidim_init_menu(
|
||||||
|
mut commands: Commands,
|
||||||
|
assets: Res<AssetServer>
|
||||||
|
) {
|
||||||
|
commands.spawn(menu_bundle(&assets));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn multidim_init_2d(
|
||||||
|
mut commands: Commands,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
meshes: ResMut<Assets<Mesh>>,
|
||||||
|
materials: ResMut<Assets<ColorMaterial>>,
|
||||||
|
) {
|
||||||
|
commands.spawn(bundle_2d(&asset_server, meshes, materials));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn multidim_init_3d(
|
||||||
|
mut commands: Commands,
|
||||||
|
meshes: ResMut<Assets<Mesh>>,
|
||||||
|
materials: ResMut<Assets<StandardMaterial>>,
|
||||||
|
) {
|
||||||
|
commands.spawn(bundle_3d(meshes, materials));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn uninit_menu_dimension(
|
||||||
|
mut commands: Commands,
|
||||||
|
menu: Single<Entity, With<Menu>>,
|
||||||
|
) {
|
||||||
|
commands.entity(*menu).try_despawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn uninit_2d(
|
||||||
|
mut commands: Commands,
|
||||||
|
two_d: Single<Entity, With<TwoD>>,
|
||||||
|
) {
|
||||||
|
commands.entity(*two_d).try_despawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn uninit_3d(
|
||||||
|
mut commands: Commands,
|
||||||
|
three_d: Single<Entity, With<ThreeD>>
|
||||||
|
) {
|
||||||
|
commands.entity(*three_d).try_despawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn multidim_switch_menu_to_2d(
|
||||||
|
_e: On<Activate>,
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
commands.run_system_cached(uninit_menu_dimension);
|
||||||
|
commands.run_system_cached(multidim_init_2d);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn multidim_switch_menu_to_3d(
|
||||||
|
_e: On<Activate>,
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
commands.run_system_cached(uninit_menu_dimension);
|
||||||
|
commands.run_system_cached(multidim_init_3d);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn multidim_switch_2d_to_menu(
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
commands.run_system_cached(uninit_2d);
|
||||||
|
commands.run_system_cached(multidim_init_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn multidim_switch_3d_to_menu(
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
commands.run_system_cached(uninit_3d);
|
||||||
|
commands.run_system_cached(multidim_init_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct MultidimPlugin;
|
||||||
|
|
||||||
|
impl Plugin for MultidimPlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app
|
||||||
|
.add_observer(button_on_interaction::<Add, Pressed>)
|
||||||
|
.add_observer(button_on_interaction::<Remove, Pressed>)
|
||||||
|
.add_observer(button_on_interaction::<Add, InteractionDisabled>)
|
||||||
|
.add_observer(button_on_interaction::<Remove, InteractionDisabled>)
|
||||||
|
.add_observer(button_on_interaction::<Insert, Hovered>)
|
||||||
|
.add_systems(Startup, multidim_init_menu)
|
||||||
|
.add_systems(Update, handle_escape.run_if(input_just_released(KeyCode::Escape)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
App::new()
|
||||||
|
.add_plugins((
|
||||||
|
DefaultPlugins,
|
||||||
|
UiWidgetsPlugins,
|
||||||
|
InputDispatchPlugin,
|
||||||
|
MultidimPlugin,
|
||||||
|
))
|
||||||
|
.run();
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue