Derive Macro bevy::reflect::Reflect

#[derive(Reflect)]
{
    // Attributes available to this derive:
    #[reflect]
    #[reflect_value]
    #[type_path]
    #[type_name]
}
Expand description

The main derive macro used by bevy_reflect for deriving its Reflect trait.

This macro can be used on all structs and enums (unions are not supported). It will automatically generate implementations for Reflect, Typed, GetTypeRegistration, and FromReflect. And, depending on the item’s structure, will either implement Struct, TupleStruct, or Enum.

See the FromReflect derive macro for more information on how to customize the FromReflect implementation.

Container Attributes

This macro comes with some helper attributes that can be added to the container item in order to provide additional functionality or alter the generated implementations.

In addition to those listed, this macro can also use the attributes for TypePath derives.

#[reflect(Ident)]

The #[reflect(Ident)] attribute is used to add type data registrations to the GetTypeRegistration implementation corresponding to the given identifier, prepended by Reflect.

For example, #[reflect(Foo, Bar)] would add two registrations: one for ReflectFoo and another for ReflectBar. This assumes these types are indeed in-scope wherever this macro is called.

This is often used with traits that have been marked by the #[reflect_trait] macro in order to register the type’s implementation of that trait.

Default Registrations

The following types are automatically registered when deriving Reflect:

  • ReflectFromReflect (unless opting out of FromReflect)
  • SerializationData
  • ReflectFromPtr

Special Identifiers

There are a few “special” identifiers that work a bit differently:

  • #[reflect(Debug)] will force the implementation of Reflect::reflect_debug to rely on the type’s [Debug] implementation. A custom implementation may be provided using #[reflect(Debug(my_debug_func))] where my_debug_func is the path to a function matching the signature: (&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result.
  • #[reflect(PartialEq)] will force the implementation of Reflect::reflect_partial_eq to rely on the type’s [PartialEq] implementation. A custom implementation may be provided using #[reflect(PartialEq(my_partial_eq_func))] where my_partial_eq_func is the path to a function matching the signature: (&self, value: &dyn #bevy_reflect_path::Reflect) -> bool.
  • #[reflect(Hash)] will force the implementation of Reflect::reflect_hash to rely on the type’s [Hash] implementation. A custom implementation may be provided using #[reflect(Hash(my_hash_func))] where my_hash_func is the path to a function matching the signature: (&self) -> u64.
  • #[reflect(Default)] will register the ReflectDefault type data as normal. However, it will also affect how certain other operations are performed in order to improve performance and/or robustness. An example of where this is used is in the FromReflect derive macro, where adding this attribute will cause the FromReflect implementation to create a base value using its [Default] implementation avoiding issues with ignored fields (for structs and tuple structs only).

#[reflect_value]

The #[reflect_value] attribute (which may also take the form #[reflect_value(Ident)]), denotes that the item should implement Reflect as though it were a base value type. This means that it will forgo implementing Struct, TupleStruct, or Enum.

Furthermore, it requires that the type implements [Clone]. If planning to serialize this type using the reflection serializers, then the Serialize and Deserialize traits will need to be implemented and registered as well.

#[reflect(from_reflect = false)]

This attribute will opt-out of the default FromReflect implementation.

This is useful for when a type can’t or shouldn’t implement FromReflect, or if a manual implementation is desired.

Note that in the latter case, ReflectFromReflect will no longer be automatically registered.

Field Attributes

Along with the container attributes, this macro comes with some attributes that may be applied to the contained fields themselves.

#[reflect(ignore)]

This attribute simply marks a field to be ignored by the reflection API.

This allows fields to completely opt-out of reflection, which may be useful for maintaining invariants, keeping certain data private, or allowing the use of types that do not implement Reflect within the container.

#[reflect(skip_serializing)]

This works similar to #[reflect(ignore)], but rather than opting out of all of reflection, it simply opts the field out of both serialization and deserialization. This can be useful when a field should be accessible via reflection, but may not make sense in a serialized form, such as computed data.

What this does is register the SerializationData type within the GetTypeRegistration implementation, which will be used by the reflection serializers to determine whether or not the field is serializable.