-
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
af1b4c5
commit aa96197
Showing
1 changed file
with
201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
# Bevy Virtual Joystick | ||
[![Crates.io](https://img.shields.io/crates/v/virtual_joystick)](https://crates.io/crates/virtual_joystick) | ||
|
||
Create and use a Virtual Joystick in a UI for [bevy](https://bevyengine.org/) Game Engine. | ||
|
||
# Versions | ||
Aviable and compatible versions | ||
|
||
| bevy | VirtualJoystick | | ||
| 0.10.1 | 0.1.0 | | ||
|
||
# Features | ||
- Support Mouse and Touch | ||
- Easy usage | ||
- Multiple types of joystick behaviour | ||
- Support Axis block (Horizontal, Vertical or Both) | ||
|
||
### Axis | ||
- Both | ||
- Horizontal | ||
- Vertical | ||
|
||
### Joystick Types | ||
- Fixed | ||
- Floating | ||
- Dynamic | ||
|
||
# Examples | ||
- [Mobile](./examples/simple_mobile) | ||
- [Desktop](./examples/simple_pc) | ||
|
||
# Usage | ||
Check out the [examples](./examples) for details. | ||
|
||
Add to Cargo.toml | ||
```toml | ||
[dependencies] | ||
bevy = "0.10.1" | ||
virtual_joystick = "*" # Add your version | ||
``` | ||
|
||
The minimal requirement: | ||
```rs | ||
use bevy::prelude::*; | ||
// import crate | ||
use virtual_joystick::*; | ||
|
||
#[bevy_main] | ||
fn main() { | ||
App::new() | ||
.add_plugins(DefaultPlugins) | ||
// Add plugin to application | ||
.add_plugin(VirtualJoystickPlugin) | ||
.run() | ||
} | ||
``` | ||
|
||
Create Joystick | ||
```rs | ||
#[bevy_main] | ||
fn main() { | ||
App::new() | ||
.add_plugins(DefaultPlugins) | ||
// Add plugin to application | ||
.add_plugin(VirtualJoystickPlugin) | ||
// Create system | ||
.add_startup_system(create_scene) | ||
// update System | ||
.add_system(update_player) | ||
.run() | ||
} | ||
|
||
|
||
fn create_scene(mut cmd: Commands, asset_server: Res<AssetServer>) { | ||
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., | ||
}) | ||
.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 | ||
```rs | ||
|
||
fn update_joystick( | ||
mut joystick: EventReader<VirtualJoystickEvent>, | ||
mut player: Query<(&mut Transform, &Player)>, | ||
time_step: Res<FixedTime>, | ||
) { | ||
// Get player | ||
let (mut player, player_data) = player.single_mut(); | ||
|
||
// Iter each joystick event | ||
for j in joystick.iter() { | ||
// get axis value 0-1 in x & y | ||
let Vec2 { x, y } = j.axis(); | ||
// 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 | ||
|
||
```rs | ||
// Resource | ||
enum VirtualJoystickAxis { | ||
Both, // Default | ||
Horizontal, | ||
Vertical, | ||
} | ||
|
||
// Resource | ||
enum VirtualJoystickType { | ||
/// Static position | ||
Fixed, | ||
/// Spawn at point click | ||
/// Default | ||
Floating, | ||
/// Follow point on drag | ||
Dynamic, | ||
} | ||
|
||
// Component | ||
struct VirtualJoystickNode { | ||
/// Image for background or border image on joystick | ||
pub border_image: Handle<Image>, | ||
/// Image for handler knob on joystick | ||
pub knob_image: Handle<Image>, | ||
/// Size for knob on joystick | ||
pub knob_size: Vec2, | ||
/// Zone to ignore movement | ||
pub dead_zone: f32, | ||
} | ||
|
||
// EventReader | ||
struct VirtualJoystickEvent { | ||
/// Raw position of point (Mouse or Touch) | ||
pub fn value(&self) -> Vec2; | ||
|
||
/// Axis of Joystick see [crate::VirtualJoystickAxis] | ||
pub fn direction(&self) -> VirtualJoystickAxis; | ||
|
||
/// Delta value ranging from 0 to 1 in each vector (x and y) | ||
pub fn axis(&self) -> Vec2; | ||
|
||
/// Delta value snaped | ||
/// warn: Still working, not working properly | ||
pub fn snap_value(&self) -> 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 | ||
- Add more documentation | ||
- Fix size on mobile build (please check this [issue](https://github.com/bevyengine/bevy/issues/8322)) |