Neigaard
Neigaard

Reputation: 4050

Getting started with pure ECS

I am trying to get started with pure ECS in Unity 2018.3.6f1, I am starting simple by just having a sphere prefab move in one direction, but I am getting no prefabs created it seems.

I have a empty game object prefab with a RenderMesh that has a Sphere mesh and a simple material, and I have this script attached to the prefab also:

using System;
using Unity.Entities;
using UnityEngine;

[Serializable]
public struct Position : IComponentData
{
    public Vector3 Value;
}

public class BoidPositionComponent : ComponentDataProxy<Position> { }

Then I have this SteeringSystem:

using System.Collections;
using System.Collections.Generic;
using Unity.Entities;
using Unity.Jobs;
using Unity.Burst;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

public class SteeringSystem : JobComponentSystem
{
    [BurstCompile]
    struct SteeringJob : IJobProcessComponentData<Position>
    {
        public float deltaTime;

        public void Execute(ref Position position)
        {
            Vector3 value = position.Value;
            value = new Vector3(value.x + deltaTime + 1.0f, value.y, value.z);
            position.Value = value;
        }
    }

    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        SteeringJob steeringJob = new SteeringJob
        {
            deltaTime = Time.deltaTime
        };
        JobHandle jobHandle = steeringJob.Schedule(this, inputDeps);
        return jobHandle;
    }
}

And lastly I have a empty game object in my scene with this script on:

using Unity.Entities;
using Unity.Rendering;
using Unity.Collections;
using UnityEngine;

public class ECSWorld : MonoBehaviour
{
    public GameObject boidPrefab;

    private static EntityManager entityManager;
    private static RenderMesh renderMesh;
    private static EntityArchetype entityArchetype;

    // Start is called before the first frame update
    void Start()
    {
        entityManager = World.Active.GetOrCreateManager<EntityManager>();
        entityArchetype = entityManager.CreateArchetype(typeof(Position));
        AddBoids();
    }

    void AddBoids()
    {
        int amount = 200;
        NativeArray<Entity> entities = new NativeArray<Entity>(amount, Allocator.Temp);
        entityManager.Instantiate(boidPrefab, entities);
        for (int i = 0; i < amount; i++)
        {
            // Do stuff, like setting data...
            entityManager.SetComponentData(entities[i], new Position { Value = Vector3.zero });
        }
        entities.Dispose();
    }
}

But I am not seeing anything when I run the game. Should it not instanciate 200 og my prefab and have them move on the screen? What am I missing here?

Thank you
Søren

Upvotes: 3

Views: 4005

Answers (1)

Jan Thom&#228;
Jan Thom&#228;

Reputation: 13624

You will need a renderer that actually renders your boids. You have created a custom Position component, but there is no system that actually does rendering based on it. So all you do is create entities and modify your Position component in memory (you should see this in the entity debugger) but since you have no renderer, you will not see anything on screen.

For now I would suggest using the "Hybrid Renderer" package that is available in the package manager. It uses its own set of components:

  • Translation for the position in 3D space
  • Scale for the scale in world space
  • Rotation for the rotation in world space
  • RenderMeshfor the mesh to be renderer (you are already using this)

With the current ECS version you can actually just convert a classic game object into an entity by adding a "Convert To Entity" Monobehaviour to it. This makes editor-integration a lot easier as you don't need all those proxy components. The auto-conversion process will automatically add the Translation, Scale, Rotation and RenderMesh components to your ECS entity.

Upvotes: 2

Related Questions