Skip to content

Conversation

Eideren
Copy link
Collaborator

@Eideren Eideren commented Sep 30, 2025

PR Details

Prefab instantiation clones the prefab itself and returns only its content, changed it so that prefab clones its list of entities and returns that.
There doesn't seem to be that much of a difference initially, but let's dive deeper:

When cloning an object through EntityCloner, the engine, for a given property it will do one of two things

  • Either create a whole new object based on the source object of that property
  • or just pass the reference of the source to the clone.
    It does so depending on the type of the object and some other misc logic.

For objects that are fully cloned, like our Prefab, the system keeps track of the newly created object to swap any other references it finds in component properties that point to the source object by our newly created clone of that object.

Meaning that if the prefab contains a component that has a prefab property pointing to that same prefab, after cloning, the property would now point to the newly created clone of the prefab instead of the original prefab.
This may seem like expected behavior, until you consider the fact that Instantiate() does not return a new prefab, but a list of entities instead.

Entity References

The other part of this PR is to ensure that references in components to Entity that lay outside the hierarchy are not cloned. Instantiation is about cloning a hierarchy under an entity, not every entity ever referenced in the components of said entity.

I would have liked to include EntityComponent references too, but I couldn't fit them in yet, it requires a larger amount of change I'm not as confident wouldn't break users game, but at least this time around it will throw an exception in that case instead of duplicating the reference.
The reason it's not as simple is because EntityComponent do not have a specific serializer, we would need one that derive from DataContentSerializerWithReuse, the serializer for TransformComponent derives from a simple DataSerializer for example.

Also refactored a test which used a goto for no good reason. Don't get me wrong, I like gotos, but using it here just doesn't make sense.

Related Issue

Couldn't find any.

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My change requires a change to the documentation.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I have built and run the editor to try this change out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant