M crates/unified/src/client/mod.rs => crates/unified/src/client/mod.rs +12 -4
@@ 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<ReplicableCollider>>) {
+ for (entity, replicated_collider) in &q {
+ commands.entity(entity)
+ .insert(replicated_collider.to_collider());
+ }
+}
+
fn add_ball_sprite(mut commands: Commands, q: Query<Entity, Added<Ball>>, asset_server: Res<AssetServer>) {
for item in &q {
let mut sprite = Sprite::from_image(asset_server.load("textures/earth.png"));
M crates/unified/src/ecs.rs => crates/unified/src/ecs.rs +41 -2
@@ 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<Vec2>);
#[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
M crates/unified/src/server/mod.rs => crates/unified/src/server/mod.rs +3 -3
@@ 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())
M crates/unified/src/shared_plugins.rs => crates/unified/src/shared_plugins.rs +3 -2
@@ 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::<SendBallHere>(Channel::Ordered)
.replicate::<Transform>()
.replicate::<Ball>()
- .replicate::<Ground>();
+ .replicate::<Ground>()
+ .replicate::<ReplicableCollider>();
}=
\ No newline at end of file