DEV Community

Rathod Ketan
Rathod Ketan

Posted on

A Comprehensive Guide to Generating Entity Prefabs at Runtime in Unity ECS

In Unity’s Entity Component System (ECS), generating entity prefabs at runtime is a powerful feature that allows dynamic creation of game objects during gameplay. While traditional Unity uses GameObject.Instantiate to achieve this, Unity ECS takes a different approach by using the EntityManager class and its Instantiate method. This guide will cover the basics of runtime prefab generation in Unity ECS, along with example code to implement it.

Learn to generate entity prefabs at runtime in Unity ECS using EntityManager. Understand SystemAPI Query and access options like RefRW and RefRO.

For a more detailed breakdown of these concepts and additional ECS topics, feel free to visit the full post on my blog!

Key Differences: Standard Unity Prefab vs ECS Prefab

In standard Unity, prefab instantiation involves creating a script to access the prefab from the Project window and then calling Instantiate to spawn it. In Unity ECS, the process is similar but handled in a more modular way. Prefabs are converted to entities through a baking process and structured using ECS components. The prefab can then be instantiated at runtime using the EntityManager.Instantiate method.

how to create prefab in unity ecs

Baking the Prefab into ECS Entities

In Unity ECS, a baker class is required to convert a prefab GameObject into an ECS entity. Below is an example of the GeneratePrefabAuthoring class that does this conversion:

public class GeneratePrefabAuthoring : Baker<GeneratePrefab>
{
    public override void Bake(GeneratePrefab authoring)
    {
        var entity = GetEntity(authoring, TransformUsageFlags.Dynamic);
        AddComponent(entity, new GeneratePrefabStruct()
        {
            prefab = GetEntity(authoring.prefab, TransformUsageFlags.Dynamic),
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

In this code, we pass the GeneratePrefab MonoBehaviour class into the GeneratePrefabAuthoring baker, which converts the prefab into an ECS-compatible entity using GetEntity. This is stored in the GeneratePrefabStruct.

Structuring Prefab Data for ECS

We now need a struct to hold our prefab data once it’s converted to an entity. Here’s the GeneratePrefabStruct:

public struct GeneratePrefabStruct : IComponentData
{
    public Entity prefab;
}
Enter fullscreen mode Exit fullscreen mode

This struct is designed to store the entity reference of our prefab so it can be accessed and instantiated at runtime.

Instantiating Entities at Runtime Using Unity ECS

To instantiate entities at runtime, Unity ECS uses the EntityManager.Instantiate method within a system. The system queries the prefab data and instantiates the entity. Below is an example of how to implement this system using ISystem

public partial struct GeneratePrefabSystem : ISystem
{
    void OnUpdate(ref SystemState state)
    {
        foreach (var prefab in SystemAPI.Query<RefRW<GeneratePrefabStruct>>())
        {
            var newPrefab = state.EntityManager.Instantiate(prefab.ValueRW.prefab);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

In this code, we’re using a foreach loop with SystemAPI.Query to access the GeneratePrefabStruct. The RefRW provides read-write access to the prefab data, allowing us to instantiate it with the EntityManager.Instantiate method.

Using RefRW and RefRO

Unity ECS provides two access types when querying entities: RefRW and RefRO. As their names suggest, RefRW grants read and write access, while RefRO allows read-only access. This gives you the flexibility to optimize performance depending on whether you need to modify the data or not.

  • RefRW (Reference Read-Write): Grants read and write access to the queried entity data.
  • RefRO (Reference Read-Only): Grants read-only access, useful for improving performance when no modifications are needed.

Code Implementation Recap

By now, we have everything in place for runtime entity instantiation:

  1. Baking the Prefab – We use GeneratePrefabAuthoring to convert the prefab GameObject into an entity.
  2. Storing the Prefab – GeneratePrefabStruct stores the converted entity.
  3. Instantiating the Prefab – GeneratePrefabSystem instantiates the prefab at runtime using EntityManager.Instantiate.

Complete Code for Generating Entity Prefabs in Unity ECS

// GeneratePrefab MonoBehaviour class to access prefab from storage
public class GeneratePrefab : MonoBehaviour
{
    public GameObject prefab;
}

// GeneratePrefabAuthoring class to bake prefab into ECS entity
public class GeneratePrefabAuthoring : Baker<GeneratePrefab>
{
    public override void Bake(GeneratePrefab authoring)
    {
        var entity = GetEntity(authoring, TransformUsageFlags.Dynamic);
        AddComponent(entity, new GeneratePrefabStruct()
        {
            prefab = GetEntity(authoring.prefab, TransformUsageFlags.Dynamic),
        });
    }
}

// Struct to store prefab data
public struct GeneratePrefabStruct : IComponentData
{
    public Entity prefab;
}

// System to instantiate prefab at runtime
public partial struct GeneratePrefabSystem : ISystem
{
    void OnUpdate(ref SystemState state)
    {
        foreach (var prefab in SystemAPI.Query<RefRW<GeneratePrefabStruct>>())
        {
            var newPrefab = state.EntityManager.Instantiate(prefab.ValueRW.prefab);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Complete Code for Generating Entity Prefabs in Unity ECS

Wrapping Up

In this guide, we’ve covered how to generate entity prefabs at runtime in Unity ECS using EntityManager.Instantiate. The process involves baking the prefab into an entity, querying the ECS world, and finally instantiating the prefab dynamically. By understanding the differences between standard Unity prefab instantiation and ECS, and leveraging features like RefRW and RefRO, you can build more scalable and performant Unity games.

Top comments (1)

Collapse
 
rk042 profile image
Rathod Ketan

Thank You, Follow for more Unity ECS tutorials