I have a GameObject prefab that consists of a parent and 2 children. The parent only has a transform. The children both have mesh renderers for visuals. When I play, the children do not appear to be “children” of the parent entity. They are showing up outside the parent in the Entities Hierarchy. This is causing changes to the parents LocalTransform to not affect the childrens LocalTransforms. However, If I add a Mesh Filter/Renderer/Collider to the Parent GameObject, it suddenly starts working as expected (children entities are showing as children (nested) and their transforms are being affected).
Even if I add a LinkedEntityGroupAuthoring to the Parent, it still does not work.
Is this entity in a subscene and not a prefab? Entities in subscenes are optimized and have their hierarchy stripped if Unity thinks they are static. You need your baker to mark it with the correct TransformFlags to avoid this.
It is in both. The prefab is being referenced in a Directory GameObject in the subscene. Here is some sample code of the setup.
Note: The ‘MyPrefab’ GameObject is the prefab with the children. It is not directly in the subscene. There is a ‘MyDirectory’ GameObject in the subscene, with the following authoring script on it.
class MyPrefabAuthoring : MonoBehaviour {
class Baker : Baker< MyPrefabAuthoring > {
override void Bake(MyPrefabAuthoring authoring) {
}
}
}
class MyDirectoryAuthoring : MonoBehaviour {
public GameObject MyPrefab;
class Baker : Baker< MyDirectoryAuthoring > {
override void Bake(MyDirectoryAuthoring authoring) {
var entity = GetEntity(TransformUsageFlags.Dynamic);
AddComponent(entity, new MyDirectory {
MyPrefabEntity = GetEntity(MyPrefab, TransformUsageFlags.Dynamic)
});
}
}
}
struct MyDirectory : IComponentData {
Entity MyPrefabEntity
}
What TransformFlags should be used? Do I need to do special linking in the MyPrefabAuthoring?
Hi. I tried this code with the prefab that has an empty gameObject as parent and a cube as child.
And then instantiate the MyPrefabEntity in the MyDirectory in a system. the cube did appeared as a child of its parent. I’m not sure what makes the result different. TransformUsageFlags.Dynamic should be enough to tell unity that there is a parent-child relation of the transforms between two entities.
And I wonder what MyPrefabAuthoring is used for, because you bake the prefab in MyDirectoryAuthoring
I have the same issue. Played around with manually adding parent/child components to the various GOs, but nothing works. Also tried forcing the Parenting System to update. AND ChatGPT is no help…
I can only solve this by adding any type of Collider to the root element of the prefab. Otherwise, all child elements are obtained by separate entities. In addition, everything works fine if no scaling is applied to the elements in the prefab, otherwise an error will also result.
I created a [topic] with a similar problem here a couple of months ago
I tried everything i can.
A baker can’t add ecs component to another entity, even child.
BakingSystem can’t access GameObject or unity component.
Finally, I figure out it with a stupid resolution:
Add this to every child object in you prefab
using Unity.Entities;
using Unity.Transforms;
using UnityEngine;
[DisallowMultipleComponent]
class ParentAuthoring : MonoBehaviour
{
}
class ParentAuthoringBaker : Baker<ParentAuthoring>
{
public override void Bake(ParentAuthoring authoring)
{
var e = GetEntity(authoring, TransformUsageFlags.Dynamic);
var parent = GetEntity(authoring.transform.parent, TransformUsageFlags.Dynamic);
AddComponent(e, new Parent() { Value = parent });
}
}
You can use some script to do this automatically, like add this to the root object
using Unity.Entities;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
class AddParentComponentToChildren : MonoBehaviour
{
}
[CustomEditor(typeof(AddParentComponentToChildren))]
class AddParentComponentToChildrenEditor : Editor
{
AddParentComponentToChildren _target;
public void OnEnable()
{
_target = (AddParentComponentToChildren)target;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Add"))
{
var total = 0;
AddComponentToAllChildren(_target.transform, ref total);
Debug.Log($"Add parent to {total} children");
}
if (GUILayout.Button("Remove"))
{
var componets = _target.transform.GetComponentsInChildren<ParentAuthoring>();
var count = componets.Length;
foreach (var c in componets)
{
DestroyImmediate(c);
}
Debug.Log($"Removed {count}");
}
}
private void AddComponentToAllChildren(Transform parent, ref int total)
{
var count = parent.transform.childCount;
if (count == 0) return;
for (int i = 0; i < count; i++)
{
var child = parent.transform.GetChild(i);
if (child.TryGetComponent<ParentAuthoring>(out _)) continue;
child.AddComponent<ParentAuthoring>();
total++;
AddComponentToAllChildren(child, ref total);
}
}
}