0
\$\begingroup\$

I've used Entitas a bit and it appeared to me as a great way of creating clean, modular code. I've seen few examples of games created with this framework, and most of them were puzzles, TD's, simple RPG's, etc. Those made me come to think, that ECS like that is not suitable for games making big use of Unity built-in physics engine. Rigidbody in this case is part of View layer, but it would affect for example "position" component, so we can't say they are really separated. Unity Physics also works at it's own pace, so there is not really a chance for independent Component-System based simulation.

Are there any generally accepted solutions, or if I don't wan't to write my own physics engine, I should give up Entitas?

\$\endgroup\$
  • \$\begingroup\$ Unity, by sheer design, already operates on an ECS: that's what a transform, a rigid body, a monobehaviour script are: components attached to an Entity (the GameObject). \$\endgroup\$ – Draco18s Jun 5 '17 at 20:27
  • \$\begingroup\$ I've been using this engine for 2 years, so that's nothing new tome. I asked exactly about integration with this one particular framework. \$\endgroup\$ – dargemir Jun 5 '17 at 20:46
  • \$\begingroup\$ Oh, I didn't realize Entitas was a framework. \$\endgroup\$ – Draco18s Jun 5 '17 at 20:53
3
\$\begingroup\$

I literally just started looking at Entitas last night so there may be better solutions, but you could do something like the following:

Create a component to store the collisions

[UniquePrefix("has")]
public class Collisions : IComponent
{
    public List<GameObject> list;
    public bool isInitialized;
}

Create a MonoBehaviour that forwards the relevant physics events to the entity

public class CollisionReporter : MonoBehaviour
{
    public GameEntity Entity;

    private void OnCollisionEnter(Collision other)
    {
        Entity.collisions.list.Add(other.gameObject);
    }
}

Create a system that links collisions entities to gameobjects with the MonoBehaviour above and responds to the collisions

public class CollisionSystem : ReactiveSystem<GameEntity>
{

    private readonly IContext<GameEntity> _context;

    public CollisionSystem(IContext<GameEntity> context) : base(context)
    {
        _context = context;
    }

    protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
    {
        return context.CreateCollector(GameMatcher.Collisions);
    }

    protected override bool Filter(GameEntity entity)
    {
        return entity.hasCollisions;
    }

    protected override void Execute(List<GameEntity> entities)
    {
        foreach (var e in entities)
        {
            if (!e.collisions.isInitialized)
            {
                var go = new GameObject();
                go.Link(e, _context);
                // Add and configure RigidBody, Collider, etc.
                var collisionReporter = go.AddComponent<CollisionReporter>();
                collisionReporter.Entity = e;
                e.collisions.isInitialized = true;
            }


            foreach (var other in e.collisions.list)
            {
                // Do whatever collision response you need...
            }

            e.collisions.list.Clear();
        }
    }

}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.