Skip to main content

Relationship

Trait Relationship 

Source
pub trait Relationship: Component + Sized {
    type RelationshipTarget: RelationshipTarget<Relationship = Self>;

    const ALLOW_SELF_REFERENTIAL: bool = false;

    // Required methods
    fn get(&self) -> Entity;
    fn from(entity: Entity) -> Self;
    fn set_risky(&mut self, entity: Entity);

    // Provided methods
    fn on_insert(world: DeferredWorld<'_>, _: HookContext) { ... }
    fn on_discard(world: DeferredWorld<'_>, _: HookContext) { ... }
}
Expand description

A Component on a “source” Entity that references another target Entity, creating a “relationship” between them. Every Relationship has a corresponding RelationshipTarget type (and vice-versa), which exists on the “target” entity of a relationship and contains the list of all “source” entities that relate to the given “target”.

A Relationship may only be one-to-many (or one-to-one): an Entity may point to at most one Entity through the Relationship component.

The Relationship component is the “source of truth” and the RelationshipTarget component reflects that source of truth. When a Relationship component is inserted on an Entity, the corresponding RelationshipTarget component is immediately inserted on the target component if it does not already exist, and the “source” entity is automatically added to the RelationshipTarget collection (this is done via “component hooks”).

A common example of a Relationship is the parent / child relationship. Bevy ECS includes a canonical form of this via the ChildOf Relationship and the Children RelationshipTarget.

Relationship and RelationshipTarget should always be derived via the Component trait to ensure the hooks are set up properly.

§Derive

Relationship and RelationshipTarget can only be derived for structs with a single unnamed field, single named field or for named structs where one field is annotated with #[relationship]. If there are additional fields, they must all implement Default.

RelationshipTarget also requires that the relationship field is private to prevent direct mutation, ensuring the correctness of relationships.

#[derive(Component)]
#[relationship(relationship_target = Children)]
pub struct ChildOf {
    #[relationship]
    pub parent: Entity,
    internal: u8,
};

#[derive(Component)]
#[relationship_target(relationship = ChildOf)]
pub struct Children(Vec<Entity>);

A one-to-one relationship can be created by putting a single Entity in the RelationshipTarget’s field. In that case, if another entity is added to the relationship, the original entity is removed.

#[derive(Component)]
#[relationship(relationship_target = View)]
pub struct ViewOf(pub Entity);

#[derive(Component)]
#[relationship_target(relationship = ViewOf)]
pub struct View(Entity);

When deriving RelationshipTarget you can specify the #[relationship_target(linked_spawn)] attribute to automatically despawn entities stored in an entity’s RelationshipTarget when that entity is despawned:

#[derive(Component)]
#[relationship(relationship_target = Children)]
pub struct ChildOf(pub Entity);

#[derive(Component)]
#[relationship_target(relationship = ChildOf, linked_spawn)]
pub struct Children(Vec<Entity>);

By default, relationships cannot point to their own entity. If you want to allow self-referential relationships, you can use the allow_self_referential attribute:

#[derive(Component)]
#[relationship(relationship_target = PeopleILike, allow_self_referential)]
pub struct LikedBy(pub Entity);

#[derive(Component)]
#[relationship_target(relationship = LikedBy)]
pub struct PeopleILike(Vec<Entity>);

Provided Associated Constants§

Source

const ALLOW_SELF_REFERENTIAL: bool = false

If true, a relationship is allowed to point to its own entity.

Set this to true when self-relationships are semantically valid for your use case, such as Likes(self), EmployedBy(self), or a ColliderOf relationship where a collider can be attached to its own entity.

§Warning

When ALLOW_SELF is true, be careful when using recursive traversal methods like iter_ancestors or root_ancestor, as they will loop infinitely if an entity points to itself.

Required Associated Types§

Source

type RelationshipTarget: RelationshipTarget<Relationship = Self>

The Component added to the “target” entities of this Relationship, which contains the list of all “source” entities that relate to the “target”.

Required Methods§

Source

fn get(&self) -> Entity

Gets the Entity ID of the related entity.

Source

fn from(entity: Entity) -> Self

Creates this Relationship from the given entity.

Source

fn set_risky(&mut self, entity: Entity)

Changes the current Entity ID of the entity containing the RelationshipTarget to another one.

This is useful for updating the relationship without overwriting other fields stored in Self.

§Warning

This should generally not be called by user code, as modifying the related entity could invalidate the relationship. If this method is used, then the hooks on_discard have to run before and on_insert after it. This happens automatically when this method is called with EntityWorldMut::modify_component.

Prefer to use regular means of insertions when possible.

Provided Methods§

Source

fn on_insert(world: DeferredWorld<'_>, _: HookContext)

The on_insert component hook that maintains the Relationship / RelationshipTarget connection.

Source

fn on_discard(world: DeferredWorld<'_>, _: HookContext)

The on_discard component hook that maintains the Relationship / RelationshipTarget connection.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§