prefab loading
Building prefab loading
This commit is contained in:
@@ -1 +1 @@
|
|||||||
pub mod macros;
|
pub mod macros;
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
use asset_loader::create_asset_loader;
|
use asset_loader::create_asset_loader;
|
||||||
use bevy::prelude::*;
|
use bevy::{gltf::GltfMesh, prelude::*};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use shared::identifiers::ResourceIdentifier;
|
use shared::{identifiers::ResourceIdentifier, prefab_defination::*};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
buildings::{
|
buildings::{
|
||||||
basic_building::BasicBuildingInfo, conduit_building::ResourceConduitInfo,
|
conduit_building::ResourceConduitInfo, factory_building::FactoryBuildingInfo,
|
||||||
factory_building::FactoryBuildingInfo, resource_gathering::ResourceGatheringBuildingInfo,
|
resource_gathering::ResourceGatheringBuildingInfo,
|
||||||
},
|
},
|
||||||
footprint::BuildingFootprint,
|
footprint::BuildingFootprint,
|
||||||
|
prelude::Building,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Asset, TypePath, Debug, Serialize, Deserialize)]
|
#[derive(Asset, TypePath, Debug, Serialize, Deserialize)]
|
||||||
@@ -18,7 +19,8 @@ pub struct BuildingAsset {
|
|||||||
pub footprint: BuildingFootprint,
|
pub footprint: BuildingFootprint,
|
||||||
pub prefab_path: String,
|
pub prefab_path: String,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub prefab: Handle<Scene>,
|
pub prefab: Handle<Gltf>,
|
||||||
|
pub base_mesh_path: String,
|
||||||
|
|
||||||
pub cost: Vec<ResourceIdentifier>,
|
pub cost: Vec<ResourceIdentifier>,
|
||||||
pub consumption: Vec<ResourceIdentifier>,
|
pub consumption: Vec<ResourceIdentifier>,
|
||||||
@@ -27,7 +29,44 @@ pub struct BuildingAsset {
|
|||||||
pub health: u32,
|
pub health: u32,
|
||||||
|
|
||||||
pub building_type: BuildingType,
|
pub building_type: BuildingType,
|
||||||
pub animations: Vec<AnimationComponent>,
|
pub children: Option<Vec<PrefabDefination>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuildingAsset {
|
||||||
|
pub fn spawn(
|
||||||
|
&self,
|
||||||
|
pos: Vec3,
|
||||||
|
rot: Quat,
|
||||||
|
gltf: &Gltf,
|
||||||
|
commands: &mut Commands,
|
||||||
|
meshes: &Assets<GltfMesh>,
|
||||||
|
) -> Option<Entity> {
|
||||||
|
let keys: Vec<_> = gltf.named_meshes.keys().collect();
|
||||||
|
info!("{keys:#?}");
|
||||||
|
let mesh_handle = &gltf.named_meshes[&self.base_mesh_path.clone().into_boxed_str()];
|
||||||
|
if let Some(gltf_mesh) = meshes.get(mesh_handle.id()) {
|
||||||
|
let (mesh, mat) = gltf_mesh.unpack();
|
||||||
|
let mut entity = commands.spawn((
|
||||||
|
PbrBundle {
|
||||||
|
mesh,
|
||||||
|
material: mat,
|
||||||
|
transform: Transform::from_translation(pos)
|
||||||
|
.with_rotation(Quat::from_rotation_arc(Vec3::NEG_Z, Vec3::Y) * rot),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
Building,
|
||||||
|
));
|
||||||
|
if let Some(children) = &self.children {
|
||||||
|
entity.with_children(|b| {
|
||||||
|
for child in children {
|
||||||
|
child.spawn_recursive(gltf, b, meshes);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Some(entity.id());
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, TypePath)]
|
#[derive(Serialize, Deserialize, Debug, TypePath)]
|
||||||
@@ -38,11 +77,6 @@ pub enum BuildingType {
|
|||||||
ResourceConduit(ResourceConduitInfo),
|
ResourceConduit(ResourceConduitInfo),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Reflect)]
|
|
||||||
pub enum AnimationComponent {
|
|
||||||
Rotation,
|
|
||||||
Slider,
|
|
||||||
}
|
|
||||||
create_asset_loader!(
|
create_asset_loader!(
|
||||||
BuildingAssetPlugin,
|
BuildingAssetPlugin,
|
||||||
BuildingAssetLoader,
|
BuildingAssetLoader,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::f32::consts::E;
|
use std::f32::consts::E;
|
||||||
|
|
||||||
use bevy::{ecs::world::CommandQueue, prelude::*, window::PrimaryWindow};
|
use bevy::{ecs::world::CommandQueue, gltf::GltfMesh, prelude::*, window::PrimaryWindow};
|
||||||
use bevy_asset_loader::loading_state::{
|
use bevy_asset_loader::loading_state::{
|
||||||
config::{ConfigureLoadingState, LoadingStateConfig},
|
config::{ConfigureLoadingState, LoadingStateConfig},
|
||||||
LoadingStateAppExt,
|
LoadingStateAppExt,
|
||||||
@@ -87,7 +87,6 @@ fn hq_placement(
|
|||||||
mut build_queue: ResMut<BuildQueue>,
|
mut build_queue: ResMut<BuildQueue>,
|
||||||
mut next_state: ResMut<NextState<GameplayState>>,
|
mut next_state: ResMut<NextState<GameplayState>>,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
if let Some(contact) = tile_under_cursor.0 {
|
if let Some(contact) = tile_under_cursor.0 {
|
||||||
let positions = map.hex_select(&contact.tile, 3, true, |pos, h, _| pos.to_world(h));
|
let positions = map.hex_select(&contact.tile, 3, true, |pos, h, _| pos.to_world(h));
|
||||||
show_indicators(positions, &mut commands, &indicator);
|
show_indicators(positions, &mut commands, &indicator);
|
||||||
@@ -122,6 +121,8 @@ fn process_build_queue(
|
|||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
db: Res<BuildingDatabase>,
|
db: Res<BuildingDatabase>,
|
||||||
building_assets: Res<Assets<BuildingAsset>>,
|
building_assets: Res<Assets<BuildingAsset>>,
|
||||||
|
gltf_assets: Res<Assets<Gltf>>,
|
||||||
|
gltf_meshes: Res<Assets<GltfMesh>>,
|
||||||
mut building_map: ResMut<BuildingMap>,
|
mut building_map: ResMut<BuildingMap>,
|
||||||
heightmap: Res<Map>,
|
heightmap: Res<Map>,
|
||||||
) {
|
) {
|
||||||
@@ -130,16 +131,14 @@ fn process_build_queue(
|
|||||||
if let Some(building) = building_assets.get(handle.id()) {
|
if let Some(building) = building_assets.get(handle.id()) {
|
||||||
let h = heightmap.sample_height(&item.pos);
|
let h = heightmap.sample_height(&item.pos);
|
||||||
println!("Spawning {} at {}", building.name, item.pos);
|
println!("Spawning {} at {}", building.name, item.pos);
|
||||||
let e = commands.spawn((
|
if let Some(gltf) = gltf_assets.get(building.prefab.id()) {
|
||||||
SceneBundle {
|
let e = building.spawn(item.pos.to_world(h), Quat::IDENTITY, gltf, &mut commands, &gltf_meshes);
|
||||||
scene: building.prefab.clone(),
|
if let Some(b) = e {
|
||||||
transform: Transform::from_translation(item.pos.to_world(h)),
|
building_map.add_building(BuildingEntry::new(item.pos, b));
|
||||||
..Default::default()
|
}
|
||||||
},
|
} else {
|
||||||
Building,
|
warn!("Failed to spawn building");
|
||||||
));
|
}
|
||||||
|
|
||||||
building_map.add_building(BuildingEntry::new(item.pos, e.id()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
queue.queue.clear();
|
queue.queue.clear();
|
||||||
|
|||||||
Submodule game/main/assets updated: 7fa3e1fc9c...4f7ec753b1
@@ -9,6 +9,7 @@ pub mod resources;
|
|||||||
pub mod sets;
|
pub mod sets;
|
||||||
pub mod states;
|
pub mod states;
|
||||||
pub mod tags;
|
pub mod tags;
|
||||||
|
pub mod prefab_defination;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub enum Tier {
|
pub enum Tier {
|
||||||
|
|||||||
62
game/shared/src/prefab_defination.rs
Normal file
62
game/shared/src/prefab_defination.rs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
use bevy::{
|
||||||
|
gltf::{Gltf, GltfMesh},
|
||||||
|
math::{Quat, Vec3},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct PrefabDefination {
|
||||||
|
pub path: String,
|
||||||
|
pub pos: Vec3,
|
||||||
|
pub rot: Vec3,
|
||||||
|
pub children: Option<Vec<PrefabDefination>>,
|
||||||
|
pub animations: Option<Vec<AnimationComponent>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrefabDefination {
|
||||||
|
pub fn spawn_recursive(&self, gltf: &Gltf, commands: &mut ChildBuilder, meshes: &Assets<GltfMesh>) {
|
||||||
|
let mesh_handle = &gltf.named_meshes[&self.path.clone().into_boxed_str()];
|
||||||
|
if let Some(gltf_mesh) = meshes.get(mesh_handle.id()) {
|
||||||
|
let (m, mat) = gltf_mesh.unpack();
|
||||||
|
let mut entity = commands.spawn(PbrBundle {
|
||||||
|
mesh: m,
|
||||||
|
material: mat,
|
||||||
|
transform: Transform::from_translation(self.pos).with_rotation(Quat::from_euler(
|
||||||
|
bevy::math::EulerRot::XYZ,
|
||||||
|
self.rot.x,
|
||||||
|
self.rot.y,
|
||||||
|
self.rot.z,
|
||||||
|
)),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
if let Some(children) = &self.children {
|
||||||
|
entity.with_children(|b| {
|
||||||
|
for child in children {
|
||||||
|
child.spawn_recursive(gltf, b, meshes);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait UnpackGltfMesh {
|
||||||
|
fn unpack(&self) -> (Handle<Mesh>, Handle<StandardMaterial>);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UnpackGltfMesh for GltfMesh {
|
||||||
|
fn unpack(&self) -> (Handle<Mesh>, Handle<StandardMaterial>) {
|
||||||
|
let p = &self.primitives[0];
|
||||||
|
let mut mat: Handle<StandardMaterial> = default();
|
||||||
|
if let Some(mesh_material) = &p.material {
|
||||||
|
mat = mesh_material.clone();
|
||||||
|
}
|
||||||
|
return (p.mesh.clone(), mat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub enum AnimationComponent {
|
||||||
|
Rotation,
|
||||||
|
Slider,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user