jakobhellermann / bevy-inspector-egui

Inspector plugin for the bevy game engine
Apache License 2.0
1.18k stars 173 forks source link

[feature] Ability to add `bevy_xpbd` types at runtime using the plus button #164

Closed ActuallyHappening closed 10 months ago

ActuallyHappening commented 10 months ago

Thanks so much for this crate!

When working on bevy 0.12 apps using bevy_xpbd_3d, it is immensely useful to be able to add marker/simple components like RigidBody::Dynamic. I noticed that you can add inbuilt bevy components already like RenderLayers, can you document a way of implementing your own extensions which add this functionality?

image
ActuallyHappening commented 10 months ago

Upon further research I am actually using bevy_editor_pls, so this might be the wrong place to put this request. Please tell me if this is the case and I'll ask it elsewhere!

naomijub commented 10 months ago

You can easily add new components in editor pls by including them in this file https://github.com/jakobhellermann/bevy_editor_pls/blob/main/crates/bevy_editor_pls_default_windows/src/add.rs#L151

I guess it would look something like state.add("Bevy XPBD", AddItem::component::<RigidBody>()); or state.add("3D Physics", AddItem::component::<RigidBody>());. If you want to make a pull request, I would consider hiding it in a feature so people can decide which physics crate to use (Rapier, XPBD or None)

ActuallyHappening commented 10 months ago

Thanks so much!

I was actually thinking of putting the relevant code into bevy_xpbd itself and feature flagging it on "bevy_editor_pls". Is this possible? I'll look at the code in more depth later, but it is something an external crate can edit at runtime like a resource or component?

naomijub commented 10 months ago

You probably can do this with a build stage, similar to what capnproto crate does. I have a terrible example on a crate called woxel-rs, in case you need some inspiration

ActuallyHappening commented 10 months ago

Is there any way of manipulating the State related to the add button window at runtime? I've taken a look but can't find any interesting resource / editor entity so I'm presuming it's not possible. Maybe introducing a public resource ExtraAddItems since &mut World is passed around everywhere anyway? I'll build out PR's for this and bevy_xpbd (xpbd's feature flagged of course) I don't quite understand bevy_editor_pls enough yet, and &mut World is not actually passed around everywhere and it seems the state is immutable most of the time?

naomijub commented 10 months ago

The problem with manipulating this in runtime is that you need the components to be registered types so that reflect takes place, and this can only be done in compile or build time. My suggestion then is that you create a file, where you declare all components that you want to use, then use a build.rs to build them into a rust code. Using cargo watch or bevy dynamic linking should help you.

File:

{"ExternalComponents":  [
  "bevy_xpbd::prelude::Mass"
 ],
"MyComponents":  [
  "MyStruct": {
    "value_a": "i32" ,
    "value_b": "String" ,
},
 ],
"resources": {}
}

Then you can have something like this https://github.com/capnproto/capnproto-rust/blob/master/capnpc/src/lib.rs#L40 that will generate code as:

#[derive(Default, Reflect, Component)]
#[reflect(Component)]
pub struct MyStruct {
  value_a: i32,
  value_b: String,
}

// Some plugin implementation
app.register_type::<bevy_xpbd::prelude::Mass>()
  .register_type::<MyStruct>()

If you have an open source code, I can probably help you there

ActuallyHappening commented 10 months ago

Maybe 'dynamically' was the wrong word, the types I want to use the + button for are already registered and defined in bevy_xpbd. I simply want the + button to be able to add them. In other words, ideally I would like an API like this:

// the names here are wrong but the idea is what I want
app.add_plugins(bevy_editor_pls::DefaultPlugin::default());
app.add_plugins(bevy_xpbd::DefaultPlugins::default());
app.world.resource_mut::<EditorContext>().cx_mut::<AddWindowState>().add_item(AddItem::component::<bevy_xpbd::RigidBody>())

The + button displays options for components stored in its EditorWindow associated type, <_ as EditorWindow>::State. I want some way to edit this state, like I can edit a resource. The .resource_mut().cx_mut() part I can't work out, nor even know if it is possible. My previous suggestion, ExtraAddItems resource, would be editable from normal Bevy ECS operations (i.e. store the data in &mut World as a resource). Trying to implement this, bevy_editor_pls doesn't propagate &mut World everywhere but does propagate state everywhere.

naomijub commented 10 months ago

Maybe how space_editor does it will help?

ActuallyHappening commented 10 months ago

They simply re-implemented part of bevy_editor_pls. This is a viable alternative I had not considered, this being Rust I can just re-implement some UI and .run_if on some state. I guess this solves my problem, but I would like to see some way of customising bevy_editor_pls. But this repo isn't even bevy_editor_pls so I'll mark this as closed.

naomijub commented 10 months ago

It is nice to have your game and the editor integrated, I strongly suggest having your own implementation of the editor