How to move kinematic bodies using ecs hybrid approach?

Hello!

I would like to try out ECS mainly to its data oriented approach, but i’m having trouble finding in the docs how to connect the dots.

So far I’ve created a game object on the scene and attached the Game Object Entity component.

and this system is taking care of moving the object:

public class MoveSystem : ComponentSystem {
    EntityQuery query;
    protected override void OnCreateManager () {
        query = GetEntityQuery (
            ComponentType.ReadOnly<Rigidbody2D> ());
    }

    protected override void OnUpdate () {
        var bodies = query.ToComponentArray<Rigidbody2D> ();

        for (int i = 0; i < bodies.Length; i++) {
            bodies[i].MovePosition (new Vector2 (bodies[i].position.x + 0.01f, 0));
        }
    }
}

Is this the right approach and workflow to sync ECS with monobehaviour objects? Also is this the only way to work with 2D in ECS?

Thanks!

I would use Entities.Foreach

public class MoveSystem : ComponentSystem {
    protected override void OnUpdate () {
        Entities.ForEach((Rigidbody2D body) =>
        {
            body.MovePosition (new Vector2 (body.position.x + 0.01f, 0));
        }
    }
}

Also have a look at the conversion workflow

Thanks a lot!

I did not manage to use the Entities.ForEach api for multiple components. e.g:

public class MoveSystem : ComponentSystem {
    protected override void OnUpdate () {
        Entities.ForEach((ref Rigidbody2D body, ref MovementSpeed speed) =>
        {
            body.MovePosition (new Vector2 (body.position.x + 0.01f, 0));
        }
    }
}

Delegate ‘EntityQueryBuilder.F_E’ does not take 2 arguments (CS1593) [Assembly-CSharp]

Reference based objects aren’t referenced via a ref keyword.

It would be:

Entities.ForEach((Rigidbody2D body, ref MovementSpeed speed) => {});

That’s true! Now it is working

From an API perspective, is there any real difference from the approaches bellow?

  Entities.ForEach((ref MovementSpeed speed, GameObjectEntity go) => {
                Rigidbody2D body =  go.GetComponent<Rigidbody2D>(); // This might hurt a little bit since it requests for a mono

                body.velocity = new Vector2(speed.Value.x, speed.Value.y);
            });
            Entities.ForEach((Rigidbody2D body, ref MovementSpeed speed) => {
                body.velocity = new Vector2(speed.Value.x, speed.Value.y);
            });

Thanks for the supporting !

Firstly, GameObjectEntity will be deprecated in favour of the ConversionAPI, since we want to avoid linking entities with gameObjects specifically. (Dunno when but it’ll happen one day.)

The former with the ((ref MovementSpeed speed, GameObjectEntity go) => {}), requires you do a GetComponent() every frame the system updates. You still get the correct chunk though, you’re just doing an extra step to grab the Rigidbody.

The latter looks through the chunks and looks through the mappings of entity + component data to get the correct data you need. You can think of it like a database and a search through the database to get the exact data you need; for a lack of a better analogy.