Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for references between entities #187

Open
andriyDev opened this issue May 25, 2024 · 0 comments · May be fixed by #188 or #236
Open

Add support for references between entities #187

andriyDev opened this issue May 25, 2024 · 0 comments · May be fixed by #188 or #236

Comments

@andriyDev
Copy link

andriyDev commented May 25, 2024

Currently (correct me if I'm wrong), there doesn't seem to be a way to have entities in a blueprint/gltf reference each other.


Here is my proposal for this:

The core API

  1. A component storing the "identifier" that an entity should be referenced with.
  2. A resource mapping identifiers (per blueprint/gltf) to the corresponding entity.
// Component holding the identifier of the thing being referenced.
// Private so it can only be accessed in Blender.
struct GltfRefTarget(String);

// Resource mapping the gltf instance + ref identifier to the entity holding that identifier.
// Public so users can write their own custom components that take refs (see below).
pub struct GltfRefMap(HashMap<(Entity, String), Entity>)

We then update this map every frame based on the existing ref targets (and remove all ref targets each frame). Now component can lookup references when a blueprint is loaded. Note this means the references can only be accessed for the first frame. This seems fine since these references should only exist to create "normal" entity relations.

Convenience API for single-entity references

While we can get the references from the GltfRefMap, for the simplest case (a component containing only one entity reference), it would be nice to avoid as much boilerplate as possible. We can achieve this with another component, a trait, and a plugin:

// Component holding the identifier for the entity we want to reference.
// Private so it can only be accessed in Blender.
struct GltfRef<T: FromGltfRef>{
  target: String,
  _marker: PhantomData<T>,
};

// Trait to convert a referenced entity into the corresponding component.
// Public so users can define this conversion for their types.
pub trait FromGltfRef {
  fn from_ref(entity: Entity) -> Self;
}

// Registers the `GltfRef<T>` type and adds a system after updating the `GltfRefMap` to replace `GltfRef<T>` with `T::from_ref`.
pub struct GltfRefPlugin<T: FromGltfRef>;

Caveats

  • We can't handle every way of spawning Gltfs. We need to be able to differentiate between the same identifier used by different instances of the same Gltf/Blueprint. While this works for Blueprints (since Blueprints always have a BlueprintName component at their root), Gltfs can be spawned in all sorts of ways. Thankfully for the common case, we can handle Gltfs without blueprints by looking for the Handle<Scene> component.
  • Blueprints in blueprints cannot reference each other's entities. This would require a much more sophisticated naming scheme and for a v0 it might be overkill. I'm not sure how common Blueprints inside other blueprints is too.
@andriyDev andriyDev linked a pull request May 25, 2024 that will close this issue
This was referenced Aug 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant