diff --git a/art/foxtrot.blend b/art/foxtrot.blend index 5b9b1a8a..b64f03ac 100644 Binary files a/art/foxtrot.blend and b/art/foxtrot.blend differ diff --git a/assets/blueprints/Fox.glb b/assets/blueprints/Fox.glb new file mode 100644 index 00000000..208ef0fe Binary files /dev/null and b/assets/blueprints/Fox.glb differ diff --git a/assets/blueprints/Fox.meta.ron b/assets/blueprints/Fox.meta.ron new file mode 100644 index 00000000..5097f2fd --- /dev/null +++ b/assets/blueprints/Fox.meta.ron @@ -0,0 +1,5 @@ +( + assets: + [ + ] +) \ No newline at end of file diff --git a/assets/levels/World.glb b/assets/levels/World.glb index 664e76bf..19fa16b5 100644 Binary files a/assets/levels/World.glb and b/assets/levels/World.glb differ diff --git a/assets/levels/World.meta.ron b/assets/levels/World.meta.ron index 2c0196e3..5b9be099 100644 --- a/assets/levels/World.meta.ron +++ b/assets/levels/World.meta.ron @@ -1,10 +1,8 @@ ( assets: [ - ("Bike", File ( path: "blueprints/Bike.glb" )), - ("Bike", File ( path: "materials/Bike.glb" )), - ("Box", File ( path: "blueprints/Box.glb" )), - ("citybits_texture", File ( path: "materials/citybits_texture.glb" )), + ("Fox", File ( path: "blueprints/Fox.glb" )), + ("fox_material", File ( path: "materials/fox_material.glb" )), ("Sidewalk Side", File ( path: "blueprints/Sidewalk Side.glb" )), ("Sidewalk", File ( path: "materials/Sidewalk.glb" )), ("Sidewalk Center", File ( path: "blueprints/Sidewalk Center.glb" )), @@ -20,66 +18,66 @@ ("Road Corner Curved", File ( path: "blueprints/Road Corner Curved.glb" )), ("citybits_texture", File ( path: "materials/citybits_texture.glb" )), ("Car Blue", File ( path: "blueprints/Car Blue.glb" )), + ("Blue", File ( path: "materials/Blue.glb" )), + ("Headlights", File ( path: "materials/Headlights.glb" )), + ("Windows", File ( path: "materials/Windows.glb" )), + ("TailLights", File ( path: "materials/TailLights.glb" )), ("Grey", File ( path: "materials/Grey.glb" )), ("Black", File ( path: "materials/Black.glb" )), - ("TailLights", File ( path: "materials/TailLights.glb" )), - ("Windows", File ( path: "materials/Windows.glb" )), - ("Headlights", File ( path: "materials/Headlights.glb" )), - ("Blue", File ( path: "materials/Blue.glb" )), ("Building Red", File ( path: "blueprints/Building Red.glb" )), - ("brick_shade1", File ( path: "materials/brick_shade1.glb" )), - ("wood", File ( path: "materials/wood.glb" )), - ("sandstone", File ( path: "materials/sandstone.glb" )), - ("concrete", File ( path: "materials/concrete.glb" )), ("brick_shade2", File ( path: "materials/brick_shade2.glb" )), ("window_glass", File ( path: "materials/window_glass.glb" )), ("window_frame", File ( path: "materials/window_frame.glb" )), - ("Building Red Corner", File ( path: "blueprints/Building Red Corner.glb" )), - ("brick_shade1", File ( path: "materials/brick_shade1.glb" )), + ("sandstone", File ( path: "materials/sandstone.glb" )), ("wood", File ( path: "materials/wood.glb" )), + ("brick_shade1", File ( path: "materials/brick_shade1.glb" )), ("concrete", File ( path: "materials/concrete.glb" )), - ("sandstone", File ( path: "materials/sandstone.glb" )), + ("Building Red Corner", File ( path: "blueprints/Building Red Corner.glb" )), ("brick_shade2", File ( path: "materials/brick_shade2.glb" )), ("window_glass", File ( path: "materials/window_glass.glb" )), ("window_frame", File ( path: "materials/window_frame.glb" )), + ("sandstone", File ( path: "materials/sandstone.glb" )), + ("wood", File ( path: "materials/wood.glb" )), + ("brick_shade1", File ( path: "materials/brick_shade1.glb" )), + ("concrete", File ( path: "materials/concrete.glb" )), ("Building Beige", File ( path: "blueprints/Building Beige.glb" )), ("brick_shadeGreen2", File ( path: "materials/brick_shadeGreen2.glb" )), + ("window_glass", File ( path: "materials/window_glass.glb" )), ("door_white", File ( path: "materials/door_white.glb" )), + ("window_frame", File ( path: "materials/window_frame.glb" )), ("sandstone", File ( path: "materials/sandstone.glb" )), ("concrete", File ( path: "materials/concrete.glb" )), ("brick_shadeGreen", File ( path: "materials/brick_shadeGreen.glb" )), - ("window_glass", File ( path: "materials/window_glass.glb" )), - ("window_frame", File ( path: "materials/window_frame.glb" )), ("Building Beige Corner Pizza", File ( path: "blueprints/Building Beige Corner Pizza.glb" )), ("brick_shadeGreen2", File ( path: "materials/brick_shadeGreen2.glb" )), - ("window_frame", File ( path: "materials/window_frame.glb" )), - ("concrete", File ( path: "materials/concrete.glb" )), - ("sandstone", File ( path: "materials/sandstone.glb" )), - ("brick_shadeGreen", File ( path: "materials/brick_shadeGreen.glb" )), - ("red", File ( path: "materials/red.glb" )), ("window_glass", File ( path: "materials/window_glass.glb" )), ("door_white", File ( path: "materials/door_white.glb" )), + ("window_frame", File ( path: "materials/window_frame.glb" )), ("White", File ( path: "materials/White.glb" )), + ("red", File ( path: "materials/red.glb" )), + ("sandstone", File ( path: "materials/sandstone.glb" )), + ("concrete", File ( path: "materials/concrete.glb" )), + ("brick_shadeGreen", File ( path: "materials/brick_shadeGreen.glb" )), ("Building Black", File ( path: "blueprints/Building Black.glb" )), ("brick_shade3", File ( path: "materials/brick_shade3.glb" )), - ("concrete", File ( path: "materials/concrete.glb" )), - ("sandstone", File ( path: "materials/sandstone.glb" )), ("window_glass", File ( path: "materials/window_glass.glb" )), ("window_frame", File ( path: "materials/window_frame.glb" )), - ("Building Red Barren", File ( path: "blueprints/Building Red Barren.glb" )), - ("brick_shade1", File ( path: "materials/brick_shade1.glb" )), ("sandstone", File ( path: "materials/sandstone.glb" )), ("concrete", File ( path: "materials/concrete.glb" )), + ("Building Red Barren", File ( path: "blueprints/Building Red Barren.glb" )), ("brick_shade2", File ( path: "materials/brick_shade2.glb" )), ("window_glass", File ( path: "materials/window_glass.glb" )), ("window_frame", File ( path: "materials/window_frame.glb" )), + ("sandstone", File ( path: "materials/sandstone.glb" )), + ("brick_shade1", File ( path: "materials/brick_shade1.glb" )), + ("concrete", File ( path: "materials/concrete.glb" )), ("Buliding Big", File ( path: "blueprints/Buliding Big.glb" )), - ("Grey", File ( path: "materials/Grey.glb" )), + ("Beige", File ( path: "materials/Beige.glb" )), + ("LightYellow", File ( path: "materials/LightYellow.glb" )), ("Brown", File ( path: "materials/Brown.glb" )), + ("Grey", File ( path: "materials/Grey.glb" )), ("DarkGrey", File ( path: "materials/DarkGrey.glb" )), ("BrickRed", File ( path: "materials/BrickRed.glb" )), - ("Beige", File ( path: "materials/Beige.glb" )), - ("LightYellow", File ( path: "materials/LightYellow.glb" )), ("Air Conditioner", File ( path: "blueprints/Air Conditioner.glb" )), ("Mat", File ( path: "materials/Mat.glb" )), ("Fire Exit", File ( path: "blueprints/Fire Exit.glb" )), @@ -91,41 +89,43 @@ ("Traffic Light", File ( path: "blueprints/Traffic Light.glb" )), ("Atlas.052", File ( path: "materials/Atlas.052.glb" )), ("Mailbox", File ( path: "blueprints/Mailbox.glb" )), - ("sign", File ( path: "materials/sign.glb" )), - ("sign_shade2", File ( path: "materials/sign_shade2.glb" )), ("mailbox", File ( path: "materials/mailbox.glb" )), + ("sign_shade2", File ( path: "materials/sign_shade2.glb" )), + ("sign", File ( path: "materials/sign.glb" )), ("Trash Container", File ( path: "blueprints/Trash Container.glb" )), - ("Grey", File ( path: "materials/Grey.glb" )), - ("Green", File ( path: "materials/Green.glb" )), ("DarkGrey", File ( path: "materials/DarkGrey.glb" )), + ("Green", File ( path: "materials/Green.glb" )), + ("Grey", File ( path: "materials/Grey.glb" )), ("Cone", File ( path: "blueprints/Cone.glb" )), + ("White", File ( path: "materials/White.glb" )), ("Black", File ( path: "materials/Black.glb" )), ("Dark_gray", File ( path: "materials/Dark_gray.glb" )), ("Orange", File ( path: "materials/Orange.glb" )), - ("White", File ( path: "materials/White.glb" )), ("Trash Bag", File ( path: "blueprints/Trash Bag.glb" )), ("mat17", File ( path: "materials/mat17.glb" )), ("Bus Stop", File ( path: "blueprints/Bus Stop.glb" )), - ("LightBlue_BusStop", File ( path: "materials/LightBlue_BusStop.glb" )), ("BlueBusStop", File ( path: "materials/BlueBusStop.glb" )), + ("LightBlue_BusStop", File ( path: "materials/LightBlue_BusStop.glb" )), ("Bus Stop Sign", File ( path: "blueprints/Bus Stop Sign.glb" )), + ("White", File ( path: "materials/White.glb" )), + ("Orang", File ( path: "materials/Orang.glb" )), ("Silver", File ( path: "materials/Silver.glb" )), ("Grey", File ( path: "materials/Grey.glb" )), ("Black", File ( path: "materials/Black.glb" )), - ("Orang", File ( path: "materials/Orang.glb" )), - ("White", File ( path: "materials/White.glb" )), + ("Box", File ( path: "blueprints/Box.glb" )), + ("citybits_texture", File ( path: "materials/citybits_texture.glb" )), ("Fence Piece", File ( path: "blueprints/Fence Piece.glb" )), - ("metal_fence", File ( path: "materials/metal_fence.glb" )), + ("brick_shade2", File ( path: "materials/brick_shade2.glb" )), ("brick_shade1", File ( path: "materials/brick_shade1.glb" )), ("sandstone_light", File ( path: "materials/sandstone_light.glb" )), - ("brick_shade2", File ( path: "materials/brick_shade2.glb" )), + ("metal_fence", File ( path: "materials/metal_fence.glb" )), ("Grass", File ( path: "blueprints/Grass.glb" )), ("Grass", File ( path: "materials/Grass.glb" )), ("Fence End", File ( path: "blueprints/Fence End.glb" )), - ("metal_fence", File ( path: "materials/metal_fence.glb" )), + ("brick_shade2", File ( path: "materials/brick_shade2.glb" )), ("brick_shade1", File ( path: "materials/brick_shade1.glb" )), ("sandstone_light", File ( path: "materials/sandstone_light.glb" )), - ("brick_shade2", File ( path: "materials/brick_shade2.glb" )), + ("metal_fence", File ( path: "materials/metal_fence.glb" )), ("Bench", File ( path: "blueprints/Bench.glb" )), ("mat19", File ( path: "materials/mat19.glb" )), ("mat20", File ( path: "materials/mat20.glb" )), @@ -136,20 +136,20 @@ ("Metal Fence", File ( path: "blueprints/Metal Fence.glb" )), ("Silver", File ( path: "materials/Silver.glb" )), ("Overpass Tunnel", File ( path: "blueprints/Overpass Tunnel.glb" )), + ("citybits_texture", File ( path: "materials/citybits_texture.glb" )), ("Black", File ( path: "materials/Black.glb" )), ("concrete", File ( path: "materials/concrete.glb" )), - ("citybits_texture", File ( path: "materials/citybits_texture.glb" )), ("Overpass Block", File ( path: "blueprints/Overpass Block.glb" )), - ("concrete", File ( path: "materials/concrete.glb" )), ("citybits_texture", File ( path: "materials/citybits_texture.glb" )), + ("concrete", File ( path: "materials/concrete.glb" )), ("Npc Pizza", File ( path: "blueprints/Npc Pizza.glb" )), ("Woman", File ( path: "materials/Woman.glb" )), ("Npc Mail", File ( path: "blueprints/Npc Mail.glb" )), - ("Shirt", File ( path: "materials/Shirt.glb" )), - ("Pants", File ( path: "materials/Pants.glb" )), - ("Hair", File ( path: "materials/Hair.glb" )), ("Skin", File ( path: "materials/Skin.glb" )), - ("Eyes", File ( path: "materials/Eyes.glb" )), + ("Pants", File ( path: "materials/Pants.glb" )), ("Socks", File ( path: "materials/Socks.glb" )), + ("Eyes", File ( path: "materials/Eyes.glb" )), + ("Shirt", File ( path: "materials/Shirt.glb" )), + ("Hair", File ( path: "materials/Hair.glb" )), ] ) \ No newline at end of file diff --git a/assets/materials/BlueBusStop.001.glb b/assets/materials/BlueBusStop.001.glb new file mode 100644 index 00000000..56eb996e Binary files /dev/null and b/assets/materials/BlueBusStop.001.glb differ diff --git a/assets/materials/LightBlue_BusStop.001.glb b/assets/materials/LightBlue_BusStop.001.glb new file mode 100644 index 00000000..4122bc47 Binary files /dev/null and b/assets/materials/LightBlue_BusStop.001.glb differ diff --git a/assets/materials/fox_material.glb b/assets/materials/fox_material.glb new file mode 100644 index 00000000..070c54e3 Binary files /dev/null and b/assets/materials/fox_material.glb differ diff --git a/assets/registry.json b/assets/registry.json index dcd592e6..a867a760 100644 --- a/assets/registry.json +++ b/assets/registry.json @@ -31,6 +31,32 @@ "type": "array", "typeInfo": "Tuple" }, + "(foxtrot::character::controller::FloatHeight, foxtrot::character::controller::WalkSpeed, foxtrot::character::controller::JumpHeight)": { + "isComponent": false, + "isResource": false, + "items": false, + "long_name": "(foxtrot::character::controller::FloatHeight, foxtrot::character::controller::WalkSpeed, foxtrot::character::controller::JumpHeight)", + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/foxtrot::character::controller::FloatHeight" + } + }, + { + "type": { + "$ref": "#/$defs/foxtrot::character::controller::WalkSpeed" + } + }, + { + "type": { + "$ref": "#/$defs/foxtrot::character::controller::JumpHeight" + } + } + ], + "short_name": "(FloatHeight, WalkSpeed, JumpHeight)", + "type": "array", + "typeInfo": "Tuple" + }, "(u8, u8)": { "isComponent": false, "isResource": false, @@ -17444,6 +17470,65 @@ "type": "string", "typeInfo": "Enum" }, + "foxtrot::character::controller::FloatHeight": { + "isComponent": true, + "isResource": false, + "items": false, + "long_name": "foxtrot::character::controller::FloatHeight", + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/f32" + } + } + ], + "short_name": "FloatHeight", + "type": "array", + "typeInfo": "TupleStruct" + }, + "foxtrot::character::controller::JumpHeight": { + "isComponent": true, + "isResource": false, + "items": false, + "long_name": "foxtrot::character::controller::JumpHeight", + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/f32" + } + } + ], + "short_name": "JumpHeight", + "type": "array", + "typeInfo": "TupleStruct" + }, + "foxtrot::character::controller::WalkSpeed": { + "isComponent": true, + "isResource": false, + "items": false, + "long_name": "foxtrot::character::controller::WalkSpeed", + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/f32" + } + } + ], + "short_name": "WalkSpeed", + "type": "array", + "typeInfo": "TupleStruct" + }, + "foxtrot::character::spawn::InsertCharacterController": { + "additionalProperties": false, + "isComponent": true, + "isResource": false, + "long_name": "foxtrot::character::spawn::InsertCharacterController", + "properties": {}, + "required": [], + "short_name": "InsertCharacterController", + "type": "object", + "typeInfo": "Struct" + }, "foxtrot::collision_layer::CollisionLayerPreset": { "isComponent": true, "isResource": false, diff --git a/src/character/controller.rs b/src/character/controller.rs index dc2f88e8..7ef55164 100644 --- a/src/character/controller.rs +++ b/src/character/controller.rs @@ -7,6 +7,7 @@ use super::action::CharacterAction; use crate::system_set::VariableBeforeFixedGameSet; pub(super) fn plugin(app: &mut App) { + app.register_type::<(FloatHeight, WalkSpeed, JumpHeight)>(); app.add_plugins(( TnuaAvian3dPlugin::new(RunFixedMainLoop), TnuaControllerPlugin::new(RunFixedMainLoop), @@ -26,11 +27,14 @@ fn apply_walking( )>, ) { for (mut controller, action_state, float_height, max_speed) in &mut character_query { - let direction = action_state + let axis = action_state .axis_pair(&CharacterAction::Move) - .normalize_or_zero() - .extend(0.) - .xzy(); + .normalize_or_zero(); + let direction = Vec3 { + x: axis.x, + y: 0.0, + z: -axis.y, + }; let sprinting_factor = if action_state.pressed(&CharacterAction::Sprint) { 1.5 } else { @@ -65,14 +69,16 @@ fn apply_jumping( } } -#[derive(Debug, Default, Clone, PartialEq, Component, Reflect, Deref, DerefMut)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Component, Reflect, Deref, DerefMut)] #[reflect(Component)] /// Must be larger than the height of the entity's center from the bottom of its /// collider, or else the character will not float and Tnua will not work properly pub struct FloatHeight(pub(crate) f32); -#[derive(Debug, Default, Clone, PartialEq, Component, Reflect, Deref, DerefMut)] + +#[derive(Debug, Default, Clone, Copy, PartialEq, Component, Reflect, Deref, DerefMut)] #[reflect(Component)] pub struct WalkSpeed(pub(crate) f32); -#[derive(Debug, Default, Clone, PartialEq, Component, Reflect, Deref, DerefMut)] + +#[derive(Debug, Default, Clone, Copy, PartialEq, Component, Reflect, Deref, DerefMut)] #[reflect(Component)] pub struct JumpHeight(pub(crate) f32); diff --git a/src/character/mod.rs b/src/character/mod.rs index 51647855..44759099 100644 --- a/src/character/mod.rs +++ b/src/character/mod.rs @@ -2,7 +2,9 @@ use bevy::prelude::*; pub mod action; pub mod controller; +mod spawn; pub(super) fn plugin(app: &mut App) { - app.add_plugins((action::plugin, controller::plugin)); + app.add_plugins((action::plugin, controller::plugin, spawn::plugin)); } + diff --git a/src/character/spawn.rs b/src/character/spawn.rs new file mode 100644 index 00000000..90b35189 --- /dev/null +++ b/src/character/spawn.rs @@ -0,0 +1,33 @@ +use bevy::{ + ecs::component::{ComponentHooks, StorageType}, + prelude::*, +}; +use bevy_tnua::prelude::*; +use leafwing_input_manager::prelude::*; + +use super::action::CharacterAction; + +pub(super) fn plugin(app: &mut App) { + app.register_type::(); +} + +#[derive(Debug, Clone, Copy, Reflect)] +#[reflect(Component)] +struct InsertCharacterController; + +impl Component for InsertCharacterController { + const STORAGE_TYPE: StorageType = StorageType::Table; + + fn register_component_hooks(hooks: &mut ComponentHooks) { + hooks.on_add(|mut world, entity, _component_id| { + world + .commands() + .entity(entity) + .insert(( + TnuaControllerBundle::default(), + ActionState::::default(), + )) + .remove::(); + }); + } +} diff --git a/src/player/camera/first_person.rs b/src/player/camera/first_person.rs index 56cca677..36fcc134 100644 --- a/src/player/camera/first_person.rs +++ b/src/player/camera/first_person.rs @@ -1,11 +1,14 @@ use bevy::prelude::*; use leafwing_input_manager::prelude::*; +use crate::player::Player; + use super::PlayerCamera; pub(super) fn plugin(app: &mut App) { app.register_type::(); app.add_plugins((InputManagerPlugin::::default(),)); + app.add_systems(Update, follow_player); } #[derive(Actionlike, PartialEq, Eq, Clone, Copy, Hash, Debug, Reflect)] @@ -52,3 +55,21 @@ pub fn first_person_camera_bundle() -> impl Bundle { InputManagerBundle::with_map(CameraAction::default_input_map()), ) } + +fn follow_player( + time: Res