fix: Instantiate() behavior for Prefab and Entity references #2914
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 thingsIt 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 fromDataContentSerializerWithReuse
, the serializer forTransformComponent
derives from a simpleDataSerializer
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
Checklist