Skip to content

Commit

Permalink
feature: Debug hitbox rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
james7132 committed May 19, 2021
1 parent 5142ca8 commit 0dbc356
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 47 deletions.
7 changes: 7 additions & 0 deletions core/src/character/frame_data/hitbox.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::ScalableValue;
use bevy::render::color::Color;
use serde::{Deserialize, Serialize};
use std::cmp::{Ord, Ordering, PartialOrd};

Expand Down Expand Up @@ -50,3 +51,9 @@ pub struct Hitbox {
pub knockback_force: ScalableValue,
pub hitstun: ScalableValue,
}

impl Hitbox {
pub fn color(&self) -> Color {
Color::RED
}
}
15 changes: 14 additions & 1 deletion core/src/character/frame_data/hurtbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::{
ScalableValue,
};
use crate::{geo::Capsule3D, player::PlayerId};
use bevy::transform::components::GlobalTransform;
use bevy::{render::color::Color, transform::components::GlobalTransform};

#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
Expand All @@ -16,6 +16,19 @@ pub enum HurtboxType {
Shield,
}

impl HurtboxType {
pub fn color(&self) -> Color {
match self {
Self::Inactive => Color::GRAY,
Self::Damageable => Color::YELLOW,
Self::Intangible => Color::BLUE,
Self::Invincible => Color::GREEN,
Self::Grazing => Color::PURPLE,
Self::Shield => Color::PINK,
}
}
}

#[derive(Clone, Debug)]
pub struct Hurtbox {
pub id: u8,
Expand Down
77 changes: 36 additions & 41 deletions core/src/debug/capsule/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,35 @@ impl Plugin for DebugCapsulesPlugin {
}
}

pub struct CapsuleGenerator {
mesh: Handle<Mesh>,
pipelines: RenderPipelines,
}

impl CapsuleGenerator {
pub fn create(&self) -> CapsuleBundle {
CapsuleBundle {
mesh: self.mesh.clone_weak(),
pipelines: self.pipelines.clone(),
visible: Visible {
is_visible: true,
is_transparent: true,
},
..Default::default()
}
}
}

#[derive(Bundle, Default)]
pub struct CapsuleBundle {
mesh: Handle<Mesh>,
draw: Draw,
visible: Visible,
main_pass: base::MainPass,
pipelines: RenderPipelines,
capsule: Capsule,
}

#[derive(RenderResources, Default)]
pub struct Capsule {
pub start: Vec3,
Expand All @@ -32,7 +61,7 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut render_graph: ResMut<RenderGraph>,
) {
let mut pipeline_handle = pipelines.add(PipelineDescriptor::default_config(ShaderStages {
let pipeline_handle = pipelines.add(PipelineDescriptor::default_config(ShaderStages {
vertex: shaders.add(Shader::from_glsl(
ShaderStage::Vertex,
include_str!("capsule.vert"),
Expand All @@ -49,47 +78,13 @@ fn setup(
.add_node_edge("capsules", base::node::MAIN_PASS)
.unwrap();

commands
.spawn()
.insert(meshes.add(Mesh::from(shape::Icosphere {
commands.insert_resource(CapsuleGenerator {
mesh: meshes.add(Mesh::from(shape::Icosphere {
radius: 1.0,
subdivisions: 3,
})))
.insert(RenderPipelines::from_pipelines(vec![RenderPipeline::new(
})),
pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::new(
pipeline_handle.clone(),
)]))
.insert(Draw::default())
.insert(base::MainPass::default())
.insert(Visible {
is_visible: true,
is_transparent: true,
})
.insert(Capsule {
start: (1.0, 1.0, 0.0).into(),
end: (0.0, 2.0, 0.0).into(),
radius: 0.5,
color: Color::rgba(1.0, 1.0, 0.0, 0.25),
});

commands
.spawn()
.insert(meshes.add(Mesh::from(shape::Icosphere {
radius: 1.0,
subdivisions: 3,
})))
.insert(RenderPipelines::from_pipelines(vec![RenderPipeline::new(
pipeline_handle,
)]))
.insert(Draw::default())
.insert(base::MainPass::default())
.insert(Visible {
is_visible: true,
is_transparent: true,
})
.insert(Capsule {
start: (2.0, 0.0, 0.0).into(),
end: (4.0, 1.0, 0.0).into(),
radius: 0.25,
color: Color::rgba(1.0, 0.0, 0.0, 0.25),
});
)]),
});
}
67 changes: 63 additions & 4 deletions game/src/debug/mod.rs → game/src/debug.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
use crate::r#match::physics::Body;
use crate::r#match::{hitbox::HitboxState, physics::Body};
use bevy::{
diagnostic::{Diagnostics, FrameTimeDiagnosticsPlugin},
math::*,
prelude::*,
};
pub use fc_core::{debug::DebugLines, geo::*};
use fc_core::{
debug::{Capsule, DebugCapsulesPlugin, DebugLinesPlugin},
character::frame_data::{hitbox::Hitbox, hurtbox::Hurtbox},
debug::{Capsule, CapsuleGenerator, DebugCapsulesPlugin, DebugLinesPlugin},
player::Player,
stage::{BlastZone, RespawnPoint, SpawnPoint, Surface},
};
pub use fc_core::{debug::DebugLines, geo::*};

const CROSS_SIZE: f32 = 0.25;
const HITBOX_ALPHA: f32 = 0.25;

fn start_debug(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(TextBundle {
Expand Down Expand Up @@ -120,6 +122,59 @@ fn draw_stage_debug(
});
}

fn visualize_hitboxes(
mut commands: Commands,
generator: Res<CapsuleGenerator>,
hitboxes: Query<Entity, (With<Hitbox>, Without<Capsule>)>,
) {
hitboxes.for_each(|hitbox| {
commands.entity(hitbox).insert_bundle(generator.create());
});
}

fn visualize_hurtboxes(
mut commands: Commands,
generator: Res<CapsuleGenerator>,
hurtboxes: Query<Entity, (With<Hurtbox>, Without<Capsule>)>,
) {
hurtboxes.for_each(|hitbox| {
commands.entity(hitbox).insert_bundle(generator.create());
});
}

fn update_hitbox_debug(
mut hitboxes: Query<(
&Hitbox,
&HitboxState,
&GlobalTransform,
&mut Capsule,
&mut Visible,
)>,
) {
hitboxes.for_each_mut(|(hitbox, state, transform, mut capsule, mut visible)| {
visible.is_visible = state.enabled;
capsule.start = transform.translation;
capsule.end = state.previous_position.unwrap_or(transform.translation);
capsule.radius = hitbox.radius;
capsule.color = hitbox.color();
capsule.color.set_a(HITBOX_ALPHA);
});
}

fn update_hurtbox_debug(
mut hitboxes: Query<(&Hurtbox, &GlobalTransform, &mut Capsule, &mut Visible)>,
) {
hitboxes.for_each_mut(|(hurtbox, transform, mut capsule, mut visible)| {
let local_to_world = transform.compute_matrix();
visible.is_visible = hurtbox.is_enabled();
capsule.start = local_to_world.transform_point3(hurtbox.collider.start);
capsule.end = local_to_world.transform_point3(hurtbox.collider.end);
capsule.radius = transform.scale.max_element() * hurtbox.collider.radius;
capsule.color = hurtbox.r#type.color();
capsule.color.set_a(HITBOX_ALPHA);
});
}

pub struct FcDebugPlugin;

impl Plugin for FcDebugPlugin {
Expand All @@ -130,6 +185,10 @@ impl Plugin for FcDebugPlugin {
.add_startup_system(start_debug.system())
.add_system(update_fps_counter.system())
.add_system(draw_player_debug.system())
.add_system(draw_stage_debug.system());
.add_system(draw_stage_debug.system())
.add_system(visualize_hitboxes.system())
.add_system(visualize_hurtboxes.system())
.add_system(update_hitbox_debug.system())
.add_system(update_hurtbox_debug.system());
}
}
Empty file removed game/src/debug/hitbox.frag
Empty file.
Empty file removed game/src/debug/hitbox.rs
Empty file.
Empty file removed game/src/debug/hitbox.vert
Empty file.
2 changes: 1 addition & 1 deletion game/src/match/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use fc_core::{
use serde::{Deserialize, Serialize};

mod events;
mod hitbox;
pub mod hitbox;
mod input;
pub mod physics;
pub mod player;
Expand Down

0 comments on commit 0dbc356

Please sign in to comment.