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

Moving camera controller into separate crate in examples #4458

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8365892
moved camera controller into separate crate
ShadowCurse Apr 11, 2022
8b39709
updated to use camera controller from utils
ShadowCurse Apr 11, 2022
9b408e2
updated to use camera controller from utils
ShadowCurse Apr 11, 2022
ae8f7e5
moved examples/utils into examples_utils
ShadowCurse Apr 11, 2022
d432c8d
Merge branch 'main' into camera_movement_as_a_crate
ShadowCurse Apr 12, 2022
80c15f2
shorten the name and removed check_camera_controller
ShadowCurse Apr 12, 2022
07fc29a
explicit CameraController addition
ShadowCurse Apr 12, 2022
0e3708d
added documentation and controls printout
ShadowCurse Apr 19, 2022
ba93c80
updated controls printout
ShadowCurse Apr 19, 2022
c766fac
fixed examples_utils crate name
ShadowCurse Apr 19, 2022
de5d8f6
Merge branch 'bevyengine:main' into camera_movement_as_a_crate
ShadowCurse Apr 19, 2022
0013cd5
bumped versions
ShadowCurse Apr 19, 2022
684d9c0
Merge branch 'main' into camera_movement_as_a_crate
ShadowCurse May 12, 2022
07f538f
added mouse control changes made by Sheepyhead
ShadowCurse May 12, 2022
b27aede
Update examples_utils/src/camera.rs
ShadowCurse May 13, 2022
41529c7
Update examples_utils/src/lib.rs
ShadowCurse May 13, 2022
e71d1c4
Merge branch 'main' into camera_movement_as_a_crate
ShadowCurse May 16, 2022
cf96d2f
moved examples_utils into bevy_camera
ShadowCurse May 17, 2022
1386c66
updated examples to use bevy_camera
ShadowCurse May 17, 2022
f792fc1
renamed camera to camera_controller
ShadowCurse May 17, 2022
01caad6
added camera controller to another example
ShadowCurse May 17, 2022
86dc2ce
fixed comment
ShadowCurse May 17, 2022
28ecdb8
small refactoring
ShadowCurse May 18, 2022
1581ffe
moved bevy_camera feature to render subfeaturs
ShadowCurse May 18, 2022
55a047e
Merge branch 'main' into camera_movement_as_a_crate
ShadowCurse May 31, 2022
13c4752
switched to bevy_time
ShadowCurse Jun 1, 2022
c16244e
Merge branch 'main' into camera_movement_as_a_crate
ShadowCurse Jun 2, 2022
4e2348d
fmt
ShadowCurse Jun 2, 2022
c2c66f5
Merge branch 'main' into camera_movement_as_a_crate
ShadowCurse Jun 14, 2022
2a93d4b
Merge branch 'main' into camera_movement_as_a_crate
ShadowCurse Jul 19, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ dynamic = ["bevy_dylib"]

# Rendering support
render = [
"bevy_internal/bevy_camera",
"bevy_internal/bevy_core_pipeline",
"bevy_internal/bevy_pbr",
"bevy_internal/bevy_gltf",
Expand All @@ -54,6 +55,7 @@ render = [
# Optional bevy crates
bevy_animation = ["bevy_internal/bevy_animation"]
bevy_audio = ["bevy_internal/bevy_audio"]
bevy_camera = ["bevy_internal/bevy_camera"]
bevy_core_pipeline = ["bevy_internal/bevy_core_pipeline"]
bevy_dynamic_plugin = ["bevy_internal/bevy_dynamic_plugin"]
bevy_gilrs = ["bevy_internal/bevy_gilrs"]
Expand Down
19 changes: 19 additions & 0 deletions crates/bevy_camera/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "bevy_camera"
version = "0.8.0-dev"
edition = "2021"
description = "Provides camera controller functionality for Bevy Engine"
homepage = "https://bevyengine.org"
repository = "https://github.com/bevyengine/bevy"
license = "MIT OR Apache-2.0"
keywords = ["bevy"]

[dependencies]
# bevy
bevy_app = { path = "../bevy_app", version = "0.8.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.8.0-dev" }
bevy_input = { path = "../bevy_input", version = "0.8.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.8.0-dev" }
bevy_render = { path = "../bevy_render", version = "0.8.0-dev" }
bevy_time = { path = "../bevy_time", version = "0.8.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.8.0-dev" }
183 changes: 183 additions & 0 deletions crates/bevy_camera/src/camera_controller.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
use bevy_ecs::prelude::*;
use bevy_input::{mouse::MouseMotion, prelude::*};
use bevy_math::prelude::*;
use bevy_render::prelude::*;
use bevy_time::Time;
use bevy_transform::prelude::*;

/// Provides basic movement functionality to the attached camera
#[derive(Component)]
pub struct CameraController {
pub enabled: bool,
pub initialized: bool,
pub sensitivity: f32,
pub key_forward: KeyCode,
pub key_back: KeyCode,
pub key_left: KeyCode,
pub key_right: KeyCode,
pub key_up: KeyCode,
pub key_down: KeyCode,
pub key_run: KeyCode,
pub mouse_key_enable_mouse: MouseButton,
pub keyboard_key_enable_mouse: KeyCode,
pub walk_speed: f32,
pub run_speed: f32,
pub friction: f32,
pub pitch: f32,
pub yaw: f32,
pub velocity: Vec3,
}

impl CameraController {
pub fn print_controls(&self) {
println!(
"
===============================
======= Camera Controls =======
===============================
{:?} - Forward
{:?} - Backward
{:?} - Left
{:?} - Right
{:?} - Up
{:?} - Down
{:?} - Run
{:?}/{:?} - EnableMouse
",
self.key_forward,
self.key_back,
self.key_left,
self.key_right,
self.key_up,
self.key_down,
self.key_run,
self.mouse_key_enable_mouse,
self.keyboard_key_enable_mouse,
);
}
}

impl Default for CameraController {
fn default() -> Self {
Self {
enabled: true,
initialized: false,
sensitivity: 0.5,
key_forward: KeyCode::W,
key_back: KeyCode::S,
key_left: KeyCode::A,
key_right: KeyCode::D,
key_up: KeyCode::E,
key_down: KeyCode::Q,
key_run: KeyCode::LShift,
mouse_key_enable_mouse: MouseButton::Left,
keyboard_key_enable_mouse: KeyCode::M,
walk_speed: 5.0,
run_speed: 15.0,
friction: 0.5,
pitch: 0.0,
yaw: 0.0,
velocity: Vec3::ZERO,
}
}
}

pub fn print_controls(controller: Query<&CameraController>, mut controls_printed: Local<bool>) {
if *controls_printed {
return;
}
if let Some(controller) = controller.iter().next() {
controller.print_controls();
*controls_printed = true;
}
}

pub fn camera_controller(
time: Res<Time>,
mut mouse_events: EventReader<MouseMotion>,
mouse_button_input: Res<Input<MouseButton>>,
key_input: Res<Input<KeyCode>>,
mut move_toggled: Local<bool>,
mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
) {
let dt = time.delta_seconds();

if let Ok((mut transform, mut options)) = query.get_single_mut() {
if !options.initialized {
let (_roll, yaw, pitch) = transform.rotation.to_euler(EulerRot::ZYX);
options.yaw = yaw;
options.pitch = pitch;
options.initialized = true;
}
if !options.enabled {
return;
}

// Handle key input
let mut axis_input = Vec3::ZERO;
if key_input.pressed(options.key_forward) {
axis_input.z += 1.0;
}
if key_input.pressed(options.key_back) {
axis_input.z -= 1.0;
}
if key_input.pressed(options.key_right) {
axis_input.x += 1.0;
}
if key_input.pressed(options.key_left) {
axis_input.x -= 1.0;
}
if key_input.pressed(options.key_up) {
axis_input.y += 1.0;
}
if key_input.pressed(options.key_down) {
axis_input.y -= 1.0;
}
if key_input.just_pressed(options.keyboard_key_enable_mouse) {
*move_toggled = !*move_toggled;
}

// Apply movement update
if axis_input != Vec3::ZERO {
let max_speed = if key_input.pressed(options.key_run) {
options.run_speed
} else {
options.walk_speed
};
options.velocity = axis_input.normalize() * max_speed;
} else {
let friction = options.friction.clamp(0.0, 1.0);
options.velocity *= 1.0 - friction;
if options.velocity.length_squared() < 1e-6 {
options.velocity = Vec3::ZERO;
}
}
let forward = transform.forward();
let right = transform.right();
transform.translation += options.velocity.x * dt * right
+ options.velocity.y * dt * Vec3::Y
+ options.velocity.z * dt * forward;

// Handle mouse input
let mut mouse_delta = Vec2::ZERO;
if mouse_button_input.pressed(options.mouse_key_enable_mouse) || *move_toggled {
for mouse_event in mouse_events.iter() {
mouse_delta += mouse_event.delta;
}
}

if mouse_delta != Vec2::ZERO {
// Apply look update
let (pitch, yaw) = (
(options.pitch - mouse_delta.y * 0.5 * options.sensitivity * dt).clamp(
-0.99 * std::f32::consts::FRAC_PI_2,
0.99 * std::f32::consts::FRAC_PI_2,
),
options.yaw - mouse_delta.x * options.sensitivity * dt,
);
transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, yaw, pitch);
options.pitch = pitch;
options.yaw = yaw;
}
}
}
24 changes: 24 additions & 0 deletions crates/bevy_camera/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//! Flying camera plugin for the game engine Bevy

mod camera_controller;

#[allow(missing_docs)]
pub mod prelude {
#[doc(hidden)]
pub use crate::CameraController;
}

pub use camera_controller::*;

use bevy_app::prelude::*;

/// Simple flying camera plugin.
/// In order to function, the [`CameraController`] component should be attached to the camera entity.
#[derive(Default)]
pub struct CameraControllerPlugin;

impl Plugin for CameraControllerPlugin {
fn build(&self, app: &mut App) {
app.add_system(camera_controller).add_system(print_controls);
}
}
1 change: 1 addition & 0 deletions crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ bevy_tasks = { path = "../bevy_tasks", version = "0.8.0-dev" }
# bevy (optional)
bevy_animation = { path = "../bevy_animation", optional = true, version = "0.8.0-dev" }
bevy_audio = { path = "../bevy_audio", optional = true, version = "0.8.0-dev" }
bevy_camera = { path = "../bevy_camera", optional = true, version = "0.8.0-dev" }
bevy_core_pipeline = { path = "../bevy_core_pipeline", optional = true, version = "0.8.0-dev" }
bevy_gltf = { path = "../bevy_gltf", optional = true, version = "0.8.0-dev" }
bevy_pbr = { path = "../bevy_pbr", optional = true, version = "0.8.0-dev" }
Expand Down
6 changes: 6 additions & 0 deletions crates/bevy_internal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ pub mod audio {
pub use bevy_audio::*;
}

#[cfg(feature = "bevy_camera")]
pub mod camera {
//! Provides types and plugins for camera.
pub use bevy_camera::*;
}

#[cfg(feature = "bevy_core_pipeline")]
pub mod core_pipeline {
//! Core render pipeline.
Expand Down
16 changes: 10 additions & 6 deletions crates/bevy_internal/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@ pub use crate::{

pub use bevy_derive::{bevy_main, Deref, DerefMut};

#[doc(hidden)]
#[cfg(feature = "bevy_animation")]
pub use crate::animation::prelude::*;

#[doc(hidden)]
#[cfg(feature = "bevy_audio")]
pub use crate::audio::prelude::*;

#[doc(hidden)]
#[cfg(feature = "bevy_animation")]
pub use crate::animation::prelude::*;
#[cfg(feature = "bevy_camera")]
pub use crate::camera::prelude::*;

#[doc(hidden)]
#[cfg(feature = "bevy_core_pipeline")]
pub use crate::core_pipeline::prelude::*;

#[doc(hidden)]
#[cfg(feature = "bevy_gilrs")]
pub use crate::gilrs::*;

#[doc(hidden)]
#[cfg(feature = "bevy_pbr")]
pub use crate::pbr::prelude::*;
Expand All @@ -43,7 +51,3 @@ pub use crate::ui::prelude::*;
#[doc(hidden)]
#[cfg(feature = "bevy_dynamic_plugin")]
pub use crate::dynamic_plugin::*;

#[doc(hidden)]
#[cfg(feature = "bevy_gilrs")]
pub use crate::gilrs::*;
13 changes: 8 additions & 5 deletions examples/3d/3d_scene.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//! A simple 3D scene with light shining over a cube sitting on a plane.

use bevy::prelude::*;
use bevy::{camera::CameraControllerPlugin, prelude::*};

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(CameraControllerPlugin)
.add_startup_system(setup)
.run();
}
Expand Down Expand Up @@ -39,8 +40,10 @@ fn setup(
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
commands
.spawn_bundle(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
})
.insert(CameraController::default());
}
13 changes: 8 additions & 5 deletions examples/3d/lighting.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//! Illustrates different lights of various types and colors, some static, some moving over
//! a simple scene.

use bevy::prelude::*;
use bevy::{camera::CameraControllerPlugin, prelude::*};

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(CameraControllerPlugin)
.add_startup_system(setup)
.add_system(movement)
.add_system(animate_light_direction)
Expand Down Expand Up @@ -209,10 +210,12 @@ fn setup(
});

// camera
commands.spawn_bundle(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
commands
.spawn_bundle(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
})
.insert(CameraController::default());
}

fn animate_light_direction(
Expand Down
14 changes: 9 additions & 5 deletions examples/3d/load_gltf.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Loads and renders a glTF file as a scene.

use bevy::prelude::*;
use bevy::{camera::CameraControllerPlugin, prelude::*};

fn main() {
App::new()
Expand All @@ -9,16 +9,20 @@ fn main() {
brightness: 1.0 / 5.0f32,
})
.add_plugins(DefaultPlugins)
.add_plugin(CameraControllerPlugin)
.add_startup_system(setup)
.add_system(animate_light_direction)
.run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(Camera3dBundle {
transform: Transform::from_xyz(0.7, 0.7, 1.0).looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
..default()
});
commands
.spawn_bundle(Camera3dBundle {
transform: Transform::from_xyz(0.7, 0.7, 1.0)
.looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
..default()
})
.insert(CameraController::default());
const HALF_SIZE: f32 = 1.0;
commands.spawn_bundle(DirectionalLightBundle {
directional_light: DirectionalLight {
Expand Down
Loading