diff --git a/crates/bevy_reflect/src/serde/ser.rs b/crates/bevy_reflect/src/serde/ser.rs index 35c5107cf5..2823f2f811 100644 --- a/crates/bevy_reflect/src/serde/ser.rs +++ b/crates/bevy_reflect/src/serde/ser.rs @@ -32,12 +32,19 @@ fn get_serializable<'a, E: Error>( reflect_value: &'a dyn Reflect, type_registry: &TypeRegistry, ) -> Result, E> { + let info = reflect_value.get_represented_type_info().ok_or_else(|| { + Error::custom(format_args!( + "Type '{}' does not represent any type", + reflect_value.reflect_type_path(), + )) + })?; + let reflect_serialize = type_registry - .get_type_data::(reflect_value.type_id()) + .get_type_data::(info.type_id()) .ok_or_else(|| { Error::custom(format_args!( "Type '{}' did not register ReflectSerialize", - reflect_value.reflect_type_path() + info.type_path(), )) })?; Ok(reflect_serialize.get_serializable(reflect_value)) diff --git a/crates/bevy_reflect/src/type_registry.rs b/crates/bevy_reflect/src/type_registry.rs index a67678e836..8fc39297f3 100644 --- a/crates/bevy_reflect/src/type_registry.rs +++ b/crates/bevy_reflect/src/type_registry.rs @@ -1,4 +1,4 @@ -use crate::{serde::Serializable, Reflect, TypeInfo, TypePath, Typed}; +use crate::{serde::Serializable, FromReflect, Reflect, TypeInfo, TypePath, Typed}; use bevy_ptr::{Ptr, PtrMut}; use bevy_utils::{HashMap, HashSet, TypeIdMap}; use downcast_rs::{impl_downcast, Downcast}; @@ -461,14 +461,20 @@ pub struct ReflectSerialize { get_serializable: for<'a> fn(value: &'a dyn Reflect) -> Serializable, } -impl FromType for ReflectSerialize { +impl FromType for ReflectSerialize { fn from_type() -> Self { ReflectSerialize { get_serializable: |value| { - let value = value.downcast_ref::().unwrap_or_else(|| { - panic!("ReflectSerialize::get_serialize called with type `{}`, even though it was created for `{}`", value.reflect_type_path(), std::any::type_name::()) - }); - Serializable::Borrowed(value) + value + .downcast_ref::() + .map(|value| Serializable::Borrowed(value)) + .or_else(|| T::from_reflect(value).map(|value| Serializable::Owned(Box::new(value)))) + .unwrap_or_else(|| { + panic!( + "FromReflect::from_reflect failed when called on type `{}` with this value: {value:?}", + T::type_path(), + ); + }) }, } } diff --git a/examples/scene/scene.rs b/examples/scene/scene.rs index dac36e96d7..6b42451d88 100644 --- a/examples/scene/scene.rs +++ b/examples/scene/scene.rs @@ -114,6 +114,7 @@ fn save_scene_system(world: &mut World) { component_b, ComponentA { x: 1.0, y: 2.0 }, Transform::IDENTITY, + Name::new("joe"), )); scene_world.spawn(ComponentA { x: 3.0, y: 4.0 }); scene_world.insert_resource(ResourceA { score: 1 });