I need to create multiple entities and set their RenderMesh from an array of Mesh and Materials, and set them parent to the GameObject being converted. This doesn’t seem to work as the created entities have many components missing such as WorldRenderBounds, but even if I add them I don’t know how to calculate them. Do you have any tips on how to do this setup correctly?
Can you show us your GO conversion to entity script and generated components?
The upcoming version of the Entities package will have a new public API RenderMeshUtility.AddComponents
and an associated RenderMeshDescription
helper struct with helper constructors that make it a lot easier to populate entities with Hybrid Renderer compatible components.
That’s amazing to hear! I got it working with current version, using the code below
static float4x4 GetDefaultTransform()
{
return float4x4.TRS(float3.zero, quaternion.identity, new float3(1, 1, 1));
}
static Entity CreateEntity(EntityManager dstManager)
{
var entity = dstManager.CreateEntity();
dstManager.AddComponentData(entity, new LocalToWorld
{
Value = GetDefaultTransform(),
});
dstManager.AddComponentData(entity, new Translation
{
Value = float3.zero
});
dstManager.AddComponentData(entity, new Rotation
{
Value = quaternion.identity
});
return entity;
}
static void AddRenderMesh(Entity entity, RenderMesh renderMesh, EntityManager dstManager)
{
dstManager.AddComponent<PerInstanceCullingTag>(entity);
dstManager.AddComponent<AmbientProbeTag>(entity);
// Converting bounds to AABB could be wrong. Don't touch it unless it's broken though.
var bounds = renderMesh.mesh.bounds;
var aabb = new AABB
{
Center = bounds.center,
Extents = bounds.extents
};
dstManager.AddComponentData(entity, new RenderBounds
{
Value = aabb
});
dstManager.AddComponentData(entity, new WorldRenderBounds
{
Value = aabb
});
dstManager.AddComponentData(entity, new ChunkWorldRenderBounds
{
Value = aabb
});
dstManager.AddSharedComponentData(entity, renderMesh);
}
static void SetParent(Entity parent, Entity child, EntityManager dstManager)
{
dstManager.AddComponentData(child, new Parent
{
Value = parent
});
dstManager.AddComponentData(child, new PreviousParent
{
Value = parent,
});
dstManager.AddComponentData(child, new LocalToParent
{
Value = GetDefaultTransform(),
});
if(!dstManager.HasComponent<Child>(parent))
{
dstManager.AddBuffer<Child>(parent);
}
var childBuffer = dstManager.GetBuffer<Child>(parent);
childBuffer.Add(new Child
{
Value = child,
});
}
Edit: Code
@vectorized-runner if you using entity conversion, that doesn’t feel right. You shouldn’t be needing doing all of that.
Do you use
public class EntitiesConversion : MonoBehaviour, IConvertGameObjectToEntity, IDeclareReferencedPrefabs
approach?
This is what I use at current.
Also, it is worth to check github Unity ECS/DOTS samples.
The root object uses that conversion, but the children is only known at runtime, that’s why I needed it
You can create all required prefabs entities from entity conversion.
Then instantiate child entity from that prefab and further attach to parents if needed.
My some parent entities doesn’t have mesh and I generate them procedurally. Then I attach children, or LOD prefabs, gathered from entity conversion, instantiating needed entities and setting parents.
I add additional custom components to prefabs if required.
But I don’t need manipulating all boundary stuff manually. That is handled by Unity systems.