Bevy Virtual Joystick

VJoystick<em>Fixed</em>Preview


GitHub Workflow Status GitHub release (latest by date)

Create and use a Virtual Joystick in a UI for bevy Game Engine.

Versions

Aviable and compatible versions

| bevy | VirtualJoystick | |--------|-----------------| | 0.11 | 2.0.1 | | 0.10.1 | 1.1.2 |

Features

NOTE: To compile android projects you can use cargo-apk or the docker-rust-android project container where you don't have to install or prepare any sdk, for more details see the readme of the mobile projects

Axis

| Both (Default) | Horizontal | Vertical | |--------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------| | VJoystick<em>Fixed</em>Both | VJoystick<em>Fixed</em>Horizontal | VJoystick<em>Fixed</em>Vertical |

Joystick Types

| Fixed | Floating (Default) | Dynamic (TODO: Fix movement feel) | |--------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------| | VJoystick<em>Fixed</em>Both | VJoystick<em>Floating</em>Both | VJoystick<em>Dynamic</em>Both |

Examples

Features

toml virtual_joystick = { version = "*", default-features = false, features = [ "inspect", "serialize" ] }

Usage

Check out the examples for details.

```sh

to run example

cargo run --example simple -F=inspect ```

Add to Cargo.toml toml [dependencies] bevy = "0.10.1" virtual_joystick = "*" # Add your version

The minimal requirement: ```rust use bevy::prelude::; // import crate use virtual_joystick::;

// ID for joysticks

[derive(Default, Reflect, Hash, Clone, PartialEq, Eq)]

enum JoystickControllerID { #[default] Joystick1, Joystick2, }

[bevy_main]

fn main() { App::new() .addplugins(DefaultPlugins) // Add plugin to application .addplugin(VirtualJoystickPlugin::::default()) .run() } ```

Create Joystick ```rust

[bevy_main]

fn main() { App::new() .addplugins(DefaultPlugins) // Add plugin to application .addplugin(VirtualJoystickPlugin) // Create system .addstartupsystem(createscene) // update System .addsystem(update_player) .run() }

fn createscene(mut cmd: Commands, assetserver: Res) { cmd.spawn(Camera2dBundle::default()); cmd.spawn_empty().insert(Player(30.));

// Spawn Virtual Joystick at horizontal center
cmd.spawn(
    // Define variable for Joystick
    VirtualJoystickBundle::new(VirtualJoystickNode {
        border_image: asset_server.load("Outline.png"),
        knob_image: asset_server.load("Knob.png"),
        knob_size: Vec2::new(80., 80.),
        dead_zone: 0.,
        id: JoystickControllerID::Joystick1,
        axis: VirtualJoystickAxis::Horizontal,
        behaviour: VirtualJoystickType::Fixed,
    })
    .set_color(TintColor(Color::WHITE))
    .set_style(Style {
        size: Size::all(Val::Px(150.)),
        position_type: PositionType::Absolute,
        position: UiRect {
            left: Val::Percent(50.),
            bottom: Val::Percent(15.),
            ..default()
        },
        ..default()
    }),
)
// When you add this component you mark this area as interactable for Joystick
.insert(VirtualJoystickInteractionArea);

} ```

Use variable generated by Joystick ```rust

fn updatejoystick( mut joystick: EventReader>, mut player: Query<(&mut Transform, &Player)>, timestep: Res, ) { // Get player let (mut player, playerdata) = player.singlemut();

// Iter each joystick event
for j in joystick.iter() {
    // get axis value 0-1 in x & y
    let Vec2 { x, y } = j.axis();
    // Verify ID of joystick for movement
    match j.id() {
        JoystickControllerID::Joystick1 => {
            // Move player using joystick axis value
            player.translation.x += x * player_data.0 * time_step.period.as_secs_f32();
            player.translation.y += y * player_data.0 * time_step.period.as_secs_f32();
        }
    }
}

} ```

Types

```rust enum VirtualJoystickAxis { Both, // Default Horizontal, Vertical, }

enum VirtualJoystickType { /// Static position Fixed, /// Spawn at point click /// Default Floating, /// Follow point on drag Dynamic, }

// Component struct VirtualJoystickNode { /// Identifier of joystick /// Note: any type that implements Hash + Clone + Default + Reflect pub id: S, /// Image for background or border image on joystick pub borderimage: Handle, /// Image for handler knob on joystick pub knobimage: Handle, /// Size for knob on joystick pub knobsize: Vec2, /// Zone to ignore movement pub deadzone: f32, /// Define Axis for this joystick pub axis: VirtualJoystickAxis, /// Define the behaviour of joystick pub behaviour: VirtualJoystickType, }

// Event Type pub enum VirtualJoystickEventType { Press, Drag, Up }

// EventReader struct VirtualJoystickEvent { /// Get ID of joystick throw event pub fn id() -> S;

/// Return the Type of Joystick Event
pub fn get_type() -> VirtualJoystickEventType;

/// Raw position of point (Mouse or Touch)
pub fn value() -> Vec2;

/// Axis of Joystick see [crate::VirtualJoystickAxis]
pub fn direction() -> VirtualJoystickAxis;

/// Delta value ranging from 0 to 1 in each vector (x and y)
pub fn axis() -> Vec2;

/// Delta value snaped
pub fn snap_axis(dead_zone: Option<f32>) -> Vec2;

}

// Bundle to spawn struct VirtualJoystickBundle { pub fn new(joystick: VirtualJoystickNode) -> Self;

pub fn set_node(mut self, node: Node) -> Self;

pub fn set_style(mut self, style: Style) -> Self;

pub fn set_color(mut self, color: TintColor) -> Self;

pub fn set_focus_policy(mut self, focus_policy: FocusPolicy) -> Self;

pub fn set_transform(mut self, transform: Transform) -> Self;

pub fn set_global_transform(mut self, global_transform: GlobalTransform) -> Self;

pub fn set_visibility(mut self, visibility: Visibility) -> Self;

pub fn set_computed_visibility(mut self, computed_visibility: ComputedVisibility) -> Self;

pub fn set_z_index(mut self, z_index: ZIndex) -> Self;

} ```

TODOs