jakobhellermann / bevy-inspector-egui

Inspector plugin for the bevy game engine
Apache License 2.0
1.15k stars 169 forks source link

Option<T: Reflect> claims to be unregistered #93

Closed djeedai closed 1 year ago

djeedai commented 1 year ago

Issue

I have a type Spawner which derives Reflect. But when used as a field in a component, the world inspector complains it's not registered:

image

I even tried to explicitly register the Option<T> itself, without much luck:

app.register_type::<ParticleEffect>();
app.register_type::<Spawner>();
app.register_type::<Option<Spawner>>();

Context

The component ParticleEffect is defined here:

https://github.com/djeedai/bevy_hanabi/blob/451bd340333c2b02c4bf4b073a09834d4f242654/src/lib.rs#L237-L256

And the Spawner is here:

https://github.com/djeedai/bevy_hanabi/blob/451bd340333c2b02c4bf4b073a09834d4f242654/src/spawn.rs#L69-L99

Registration happens here in case that's relevant (the committed version doesn't contain the local changes mentioned above):

https://github.com/djeedai/bevy_hanabi/blob/451bd340333c2b02c4bf4b073a09834d4f242654/src/plugin.rs#L71-L72

Repro

git clone https://github.com/djeedai/bevy_hanabi.git
cd bevy_hanabi
cargo r --example gradient --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/png 3d"

Expand the "effect" entity, it contains a ParticleEffect component with a spawner: Option<Spawner> field.

jakobhellermann commented 1 year ago

Registering Option<Spawner> shuold be the solution here, but in bevy 0.8 Option is registered as reflect_value, i.e. completely opaque, so in bevy-inspector-egui I cannot display it because I have no way to tie the Option<Spawner> back to the Spawner type. In bevy main/0.9 Options are reflected as reflect enums, so I can dissect their structure and display them.

If you want to register an Option<T> in bevy 0.8 (or any other reflect_value type), you can use the InspectableRegistry instead, which doesn't go through reflection.

So

use bevy_inspector_egui::prelude::*;

app
    .register_inspectable::<Option<Spawner>>();

should fix your issue. This only works if Spawner derives Inspectable, it isn't enough to just be Reflect.

djeedai commented 1 year ago

Thanks @jakobhellermann! I tried but now I have another bug where I cannot expand my object nor close the inspector when using the WorldInspectorPlugin:

inspectable_bug

jakobhellermann commented 1 year ago

That's weird, I haven't seen that kind of issue. Do you only have one egui window? Sometimes I have seen similar things when there were duplicate egui ids.

djeedai commented 1 year ago

I only use bevy-inspector-egui but indeed I think I've seen some red text about duplicate ID briefly while expanded. What could cause this otherwise? Could it be manual registration via Inspectable fighting with Reflect-based one?

jakobhellermann commented 1 year ago

I don't know. Manual inspectable vs reflect should cause any issues, having two windows with the same title could but that isn't the case here...

djeedai commented 1 year ago

Update on this, bevy_hanabi is now on Bevy 0.9 with bevy-inspector-egui = "0.14", and as a local test I marked the Spawner struct as both Reflect and Inspectable, and I registered both Spawner and Option<Spawner> as types, but I'm still getting some "Reflect enum inspection is not yet implemented." message in the world inspector. Is that expected?

jakobhellermann commented 1 year ago

That's expected. 0.14 has no code to display UI for arbitrary enums, it has only #[derive(Inspectable)] on enums. If you want to use the Inspectable impl in the world inspector, you'll have to call register_inspectable. .register is not enough, it only uses reflection.

The 0.15.0-pre.0 prerelease does support enum reflection, and doesn't require any additional derives.

jakobhellermann commented 1 year ago

0.16 is now released, so using Reflect and registering .register_type::<Option<T>> should work. If not, feel free to reopen.

djeedai commented 1 year ago

I can confirm everything works out of the box with 0.17, this is awesome thanks Jakob! :)