//! A basic fps-style flycamera for bevy //! //! # Controls //! * WASD to move //! * LCTRL to descend //! * Space to ascend //! * Escape to unlock cursor //! //! The controls are customizable //! //! # Usage //! 1. Add to Cargo.toml, matching major/minor with bevy //! ``` //! [dependencies] //! bevy = "X.Y" //! bevy-fpscam = "X.Y" //! ``` //! //! 2. Use the plugin //! ``` //! use bevy_fpscam::FpsCamPlugin; //! ``` //! This will spawn the camera for you. If you want to create //! the camera yourself, use `NoSpawnFpsCamPlugin` instead, and //! add a `FpsCam` component to your camera. //! //! 3. Add the plugin //! ``` //! fn main() { //! App::new() //! .add_plugins(DefaultPlugins) //! .add_plugin(FpsCamPlugin) //! .run(); //! } //! ``` //! //! # Customization //! You can modify mouse sensitivity, movement speed and keybindings //! by modifying the resource of type `bevy_fpscam::Config` //! ``` //! fn main() { //! App::new() //! .add_plugins(DefaultPlugins) //! .add_plugin(FpsCamPlugin) //! .insert_resource(bevy_fpscam::Config{ //! movespeed: 2.0, //! sensitivity: 0.01, //! key_bindings: KeyBindings { //! unlock: Some(KeyCode::Enter), //! ..Default::default() //! }}).run(); //! } //! ``` use bevy::{ input::{ keyboard::KeyboardInput, mouse::{MouseButtonInput, MouseMotion}, ElementState, }, prelude::*, window::WindowFocused, }; /// Keybindings for controlling the camera. Default is WASD for movement, space /// for up, LCTRL for down and ESC for unlocking the cursor. All keybinds are /// optional. #[derive(Clone, Copy, Debug)] pub struct KeyBindings { pub forward: Option, pub back: Option, pub left: Option, pub right: Option, pub up: Option, pub down: Option, pub unlock: Option, } impl Default for KeyBindings { fn default() -> Self { Self { forward: Some(KeyCode::W), back: Some(KeyCode::S), left: Some(KeyCode::A), right: Some(KeyCode::D), up: Some(KeyCode::Space), down: Some(KeyCode::LControl), unlock: Some(KeyCode::Escape), } } } /// Global configuration for the camera. modify the resource of this /// type to change from the default configuration #[derive(Clone, Copy, Debug)] pub struct Config { pub movespeed: f32, pub sensitivity: f32, pub key_bindings: KeyBindings, } impl Default for Config { fn default() -> Self { Self { movespeed: 1.0, sensitivity: 0.001, key_bindings: Default::default(), } } } /// Represents the player controlled camera. Attaching this to an entity which /// has a transform will make it controllable by the player. Note that if you /// put this component on multiple entities they will all be controlled /// simultaneously by the player. #[derive(Component, Default, Debug, Clone, Copy)] pub struct FpsCam { pub yaw: f32, pub pitch: f32, } /// Handles camera movement fn camera_move( keys: Res>, time: Res