From 8f2fb8085e0a75d87209a9063ec16b1f679ec345 Mon Sep 17 00:00:00 2001 From: core Date: Mon, 30 Jun 2025 09:17:07 -0400 Subject: [PATCH] replicable colliders --- crates/unified/src/client/mod.rs | 16 ++++++++--- crates/unified/src/ecs.rs | 43 ++++++++++++++++++++++++++-- crates/unified/src/server/mod.rs | 6 ++-- crates/unified/src/shared_plugins.rs | 5 ++-- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/crates/unified/src/client/mod.rs b/crates/unified/src/client/mod.rs index 513aca353a89850f4b83395ff9b69867df2d54a8..799ccb1487267dab2e974049b43ee1ccaad53312 100644 --- a/crates/unified/src/client/mod.rs +++ b/crates/unified/src/client/mod.rs @@ -7,7 +7,7 @@ use bevy_replicon::prelude::RepliconChannels; use bevy_replicon_renet2::netcode::{ClientAuthentication, NetcodeClientTransport, NativeSocket}; use bevy_replicon_renet2::renet2::{ConnectionConfig, RenetClient}; use bevy_replicon_renet2::RenetChannelsExt; -use crate::ecs::{Ball, CursorWorldCoordinates, Ground, MainCamera, SendBallHere}; +use crate::ecs::{Ball, CursorWorldCoordinates, Ground, MainCamera, ReplicableCollider, SendBallHere}; pub struct ClientPlugin { pub server: SocketAddr @@ -40,10 +40,11 @@ impl Plugin for ClientPlugin { info!(?client_id, "connected!"); }) .add_systems(Startup, setup_graphics) - .add_systems(Update, add_ball_sprite) - .add_systems(Update, add_ground_sprite) + //.add_systems(Update, add_ball_sprite) + //.add_systems(Update, add_ground_sprite) .add_systems(Update, update_cursor_position) - .add_systems(Update, teleport_cube_around); + .add_systems(Update, teleport_cube_around) + .add_systems(Update, replicate_colliders); } } @@ -52,6 +53,13 @@ fn setup_graphics(mut commands: Commands) { .insert(MainCamera); } +fn replicate_colliders(mut commands: Commands, q: Query<(Entity, &ReplicableCollider), Added>) { + for (entity, replicated_collider) in &q { + commands.entity(entity) + .insert(replicated_collider.to_collider()); + } +} + fn add_ball_sprite(mut commands: Commands, q: Query>, asset_server: Res) { for item in &q { let mut sprite = Sprite::from_image(asset_server.load("textures/earth.png")); diff --git a/crates/unified/src/ecs.rs b/crates/unified/src/ecs.rs index a5b730ce0cf84caa44c32d9bc3988ad82286a8a9..f5b105fd6de0f32e0685e139ccfaa9873b0324a4 100644 --- a/crates/unified/src/ecs.rs +++ b/crates/unified/src/ecs.rs @@ -1,5 +1,7 @@ use bevy::math::Vec2; -use bevy::prelude::{Component, Event, Resource}; +use bevy::prelude::{Bundle, Component, Event, Resource}; +use bevy_rapier2d::math::{Real, Vect}; +use bevy_rapier2d::prelude::Collider; use serde::{Deserialize, Serialize}; #[derive(Component, Serialize, Deserialize)] @@ -12,4 +14,41 @@ pub struct MainCamera; pub struct CursorWorldCoordinates(pub Option); #[derive(Debug, Default, Deserialize, Event, Serialize)] -pub struct SendBallHere(pub Vec2); \ No newline at end of file +pub struct SendBallHere(pub Vec2); + +#[derive(Bundle)] +pub struct ReplColliderBundle(ReplicableCollider, Collider); + +#[derive(Serialize, Deserialize, Copy, Clone, Component)] +pub enum ReplicableCollider { + Ball(Real), + Cuboid { half_x: Real, half_y: Real }, + RoundCuboid { half_x: Real, half_y: Real, border_radius: Real }, + Capsule { start: Vect, end: Vect, radius: Real } +} +impl ReplicableCollider { + pub fn to_collider(&self) -> Collider { + match self { + ReplicableCollider::Ball(radius) => Collider::ball(*radius), + ReplicableCollider::Cuboid { half_x, half_y } => Collider::cuboid(*half_x, *half_y), + ReplicableCollider::RoundCuboid { half_x, half_y, border_radius } => Collider::round_cuboid(*half_x, *half_y, *border_radius), + ReplicableCollider::Capsule { start, end, radius } => Collider::capsule(*start, *end, *radius), + } + } + pub fn ball(radius: Real) -> ReplColliderBundle { + let rc = ReplicableCollider::Ball(radius); + ReplColliderBundle(rc, rc.to_collider()) + } + pub fn cuboid(half_x: Real, half_y: Real) -> ReplColliderBundle { + let rc = ReplicableCollider::Cuboid { half_x, half_y }; + ReplColliderBundle(rc, rc.to_collider()) + } + pub fn round_cuboid(half_x: Real, half_y: Real, border_radius: Real) -> ReplColliderBundle { + let rc = ReplicableCollider::RoundCuboid { half_x, half_y, border_radius }; + ReplColliderBundle(rc, rc.to_collider()) + } + pub fn capsule(start: Vect, end: Vect, radius: Real) -> ReplColliderBundle { + let rc = ReplicableCollider::Capsule { start, end, radius }; + ReplColliderBundle(rc, rc.to_collider()) + } +} \ No newline at end of file diff --git a/crates/unified/src/server/mod.rs b/crates/unified/src/server/mod.rs index 088dc6ae95575c7cf61543588f193971d8a72c20..881cb19fcebf7339713aa62a47d0f7537cd0233b 100644 --- a/crates/unified/src/server/mod.rs +++ b/crates/unified/src/server/mod.rs @@ -6,7 +6,7 @@ use bevy_replicon::prelude::{FromClient, Replicated, RepliconChannels}; use bevy_replicon_renet2::netcode::{NativeSocket, NetcodeServerTransport, ServerAuthentication, ServerSetupConfig}; use bevy_replicon_renet2::renet2::{ConnectionConfig, RenetServer}; use bevy_replicon_renet2::RenetChannelsExt; -use crate::ecs::{Ball, Ground, SendBallHere}; +use crate::ecs::{Ball, Ground, ReplicableCollider, SendBallHere}; pub struct ServerPlugin { pub bind: SocketAddr, @@ -47,14 +47,14 @@ impl Plugin for ServerPlugin { } fn setup_physics(mut commands: Commands) { - commands.spawn(Collider::cuboid(500.0, 50.0)) + commands.spawn(ReplicableCollider::cuboid(500.0, 50.0)) .insert(Transform::from_xyz(0.0, -100.0, 0.0)) .insert(Restitution::coefficient(1.0)) .insert(Ground) .insert(Replicated); commands.spawn(RigidBody::Dynamic) - .insert(Collider::ball(50.0)) + .insert(ReplicableCollider::ball(50.0)) .insert(Restitution::coefficient(1.0)) .insert(Transform::from_xyz(0.0, 400.0, 0.0)) .insert(Velocity::default()) diff --git a/crates/unified/src/shared_plugins.rs b/crates/unified/src/shared_plugins.rs index 02efe4b048ad895e542d0941ebcc0ad15f5cab99..7039b6bfb167322ce3d3b96c46e44091df5d4b82 100644 --- a/crates/unified/src/shared_plugins.rs +++ b/crates/unified/src/shared_plugins.rs @@ -2,7 +2,7 @@ use bevy::app::{App, PluginGroup, PluginGroupBuilder}; use bevy::prelude::{Sprite, Transform}; use bevy_rapier2d::prelude::*; use bevy_replicon::prelude::{AppRuleExt, Channel, ClientEventAppExt}; -use crate::ecs::{Ball, Ground, SendBallHere}; +use crate::ecs::{Ball, Ground, ReplicableCollider, SendBallHere}; pub struct SharedPluginGroup; @@ -19,5 +19,6 @@ pub fn register_everything(app: &mut App) { .add_client_event::(Channel::Ordered) .replicate::() .replicate::() - .replicate::(); + .replicate::() + .replicate::(); } \ No newline at end of file