Post by Admin on Jul 16, 2016 4:36:25 GMT
Jan Thomä @derkork Nov 26 2015 00:21
Hey there, I stepped over Entitas the other day (after implementing my own poor man's ECS) and I found it to be pretty exciting. I'm currently a bit unsure on how to incorporate user input into the ECS, e.g. things like camera control. The two example projects are very simple and only have very simple input. Is there an example which shows a bit more complex input handling with Entitas?
Maxim Zaks @mzaks Nov 26 2015 01:58
@derkork have a look at the example that @mikecann provided.
github.com/mikecann/Entitasteroids/tree/master/Assets/Entitasteroids/Scripts/Controllers
It reflects the main idea. The user input becomes state reflected by entities and will be picked up by some systems.
With this approach, it is easy to write NPCs, multi player games and also game replay.
Jan Thomä @derkork Nov 26 2015 03:34
@mzaks thanks I will check it out
Mike Cann @mikecann Nov 26 2015 08:14
@derkork Just shout if you need help
Jan Thomä @derkork Nov 26 2015 16:31
Hello again, so I had a look at the example and I managed to get some simple camera control working. However another question just struck me - is there a way to ensure that if component X is added that component Y is added as well? Something like the [RequireComponent] that's built into Unity?
It is not something that I would strictly need (in terms of 'the game wouldn't work without the feature') but it seems to be good to have something like that to avoid endless debugging sessions.
Maxim Zaks @mzaks Nov 26 2015 16:42
We don't have any "validations" or constrains in Entitas yet. This could be something to think about. It is quite simple to write something like this as a reactive system. Lets say you want to have component A and B always be present on an entity.
You can write a multi reactive system which will check when one of the components is added if the other is also present on the entity.
Same if you want to exclude two components of being present on the same entity.
You can also than keep those ValidationSystems only during development and strip them out when you go in production, so that they don't impact performance.
Jan Thomä @derkork Nov 26 2015 16:59
Makes sense. Is there some example on the MultiReactiveSystem ? I saw that it is there, but I'm not entirely sure about it's semantics. Would the Execute method be called for every entity that matches one of the given variants? And if so, would I need to introspect the given entities to find out which variant I'm having? Or does it work in a completely different way?
Also how would I find out which event occurred in a MultiReactiveSystem?
Jan Thomä @derkork Nov 26 2015 17:05
Sorry if these are somewhat noobish questions... :worried:
Maxim Zaks @mzaks Nov 26 2015 17:19
No problem
I can't find an example there is only a unit test
github.com/sschmid/Entitas-CSharp/blob/develop/Tests/Tests/Entitas/describe_ReactiveSystem.cs#L212
Not sure how helpful it is.
But anyways reactive systems monitor a group for a change.
MultiReactiveSystem can monitor multiple groups for changes. The entities that you get in the execute methods are results of the changes on those multiple groups.
When does it make sense to use those?
Lets take my validation example. We have components A and B. So we need to monitor if a group of A entities get a new member. This is done by Matcher.A.OnEntityAdded()
And if a group of B entities get a new member. Matcher.B.OnEntityAdded()
and the implementation in the execute method will be something like this:
foreach(var e in entities){
if(e.hasA && e.hasB){
continue;
} else {
throw new Exception("Boooomm");
}
}
For this we can either implement two reactive systems which will have the same implementation but different triggers, or we can have a multi reactive system with
new TriggerOnEvent[]{ Matcher.A.OnEntityAdded(),
Matcher.B.OnEntityAdded()
};
sorry for the inline chat coding
Simon Schmid @sschmid Nov 26 2015 17:33
I usually use MultiReactiveSystem to react on if any of a given set of components were added
public class MySystem : IMultiReactiveSystem
{
public TriggerOnEvent[] triggers {
get
{
return new [] {
CoreMatcher.A.OnEntityAdded(),
CoreMatcher.B.OnEntityAdded()
};
}
}
public void Execute(List<Entity> entities)
{
// entities may contain both, A or B
// since both A or B will act as a trigger
}
}
Maxim Zaks @mzaks Nov 26 2015 19:31
One more gotcha which we avoid with multi reactive system is use of anyOf matcher as a trigger. In my example where we want to validate if an entity has A or B component we might say what about having and Matcher.AnyOf(Matcher.A, Matcher.B).OnEntityAddedRemoved() as a trigger on one system.
Intuitively it feels like a good idea but it is a wrong one. A group which has A or B will be triggered when you will add A or be but it want trigger until you remove A and B. It also wan't trigger if an entity already has A and you just added B, because the entity is already in the group.
This is why my advice is to NEVER use AnyOf matcher as a reactive system trigger. It will feel right but it almost never is
Simon Schmid @sschmid Nov 26 2015 19:55
I was just fooled by this last week myself. I used AnyOf as a trigger in a normal ReactiveSystem. In most cases you should a MultiReactiveSystem for that
I had AnyOf(A, B).
I added A - the system triggered
later I added B - the system didn’t trigger? What? Why?
The entity has already been added to the group when I added A. So when I add B, nothing changes, the Entity is already in the group - no trigger.
That’s why you should use MultiReactiveSystems in this kind of scenario as it will behave as expected
It will trigger when adding A AND when adding B
Jan Thomä @derkork Nov 26 2015 22:57
I see. Well in my case I solved it differently. Basically what I had was an entity which represents a Unit had a GameObject view and a specific MonoBehaviour (a Chronos Timeline) component that i needed to access. So I added a Resource and View component to create the view from a prefab resource just like you did for the match one example (i found that to be a pretty neat way of instanciating views on demand). Now I wanted to have a Timelinecomponent which references the ChronosTimeline from the Unit prefab. Which means I have some kind of dependency here because before I can add the Timeline component, the view has to be created. So I added another component NeedsTimeline which basically works similar to the Resource view. I triggered it using a new system listening toAllOf(View, NeedsTimeline) and then added the actual Timeline component which references the Chronos timeline MonoBehaviour from the now existing view. However this seems a bit too fiddly for my taste. It works but it doesn't feel right.
Jan Thomä @derkork Nov 26 2015 23:02
But I guess I will come up with a set of design patterns over time. A really great thing about Entitas is that - even though it relies on generating code - you can easily refactor anything within the IDE. A lot better than for example UFrame ECS where your code is pretty much broken if you need to refactor anything.
Hey there, I stepped over Entitas the other day (after implementing my own poor man's ECS) and I found it to be pretty exciting. I'm currently a bit unsure on how to incorporate user input into the ECS, e.g. things like camera control. The two example projects are very simple and only have very simple input. Is there an example which shows a bit more complex input handling with Entitas?
Maxim Zaks @mzaks Nov 26 2015 01:58
@derkork have a look at the example that @mikecann provided.
github.com/mikecann/Entitasteroids/tree/master/Assets/Entitasteroids/Scripts/Controllers
It reflects the main idea. The user input becomes state reflected by entities and will be picked up by some systems.
With this approach, it is easy to write NPCs, multi player games and also game replay.
Jan Thomä @derkork Nov 26 2015 03:34
@mzaks thanks I will check it out
Mike Cann @mikecann Nov 26 2015 08:14
@derkork Just shout if you need help
Jan Thomä @derkork Nov 26 2015 16:31
Hello again, so I had a look at the example and I managed to get some simple camera control working. However another question just struck me - is there a way to ensure that if component X is added that component Y is added as well? Something like the [RequireComponent] that's built into Unity?
It is not something that I would strictly need (in terms of 'the game wouldn't work without the feature') but it seems to be good to have something like that to avoid endless debugging sessions.
Maxim Zaks @mzaks Nov 26 2015 16:42
We don't have any "validations" or constrains in Entitas yet. This could be something to think about. It is quite simple to write something like this as a reactive system. Lets say you want to have component A and B always be present on an entity.
You can write a multi reactive system which will check when one of the components is added if the other is also present on the entity.
Same if you want to exclude two components of being present on the same entity.
You can also than keep those ValidationSystems only during development and strip them out when you go in production, so that they don't impact performance.
Jan Thomä @derkork Nov 26 2015 16:59
Makes sense. Is there some example on the MultiReactiveSystem ? I saw that it is there, but I'm not entirely sure about it's semantics. Would the Execute method be called for every entity that matches one of the given variants? And if so, would I need to introspect the given entities to find out which variant I'm having? Or does it work in a completely different way?
Also how would I find out which event occurred in a MultiReactiveSystem?
Jan Thomä @derkork Nov 26 2015 17:05
Sorry if these are somewhat noobish questions... :worried:
Maxim Zaks @mzaks Nov 26 2015 17:19
No problem
I can't find an example there is only a unit test
github.com/sschmid/Entitas-CSharp/blob/develop/Tests/Tests/Entitas/describe_ReactiveSystem.cs#L212
Not sure how helpful it is.
But anyways reactive systems monitor a group for a change.
MultiReactiveSystem can monitor multiple groups for changes. The entities that you get in the execute methods are results of the changes on those multiple groups.
When does it make sense to use those?
Lets take my validation example. We have components A and B. So we need to monitor if a group of A entities get a new member. This is done by Matcher.A.OnEntityAdded()
And if a group of B entities get a new member. Matcher.B.OnEntityAdded()
and the implementation in the execute method will be something like this:
foreach(var e in entities){
if(e.hasA && e.hasB){
continue;
} else {
throw new Exception("Boooomm");
}
}
For this we can either implement two reactive systems which will have the same implementation but different triggers, or we can have a multi reactive system with
new TriggerOnEvent[]{ Matcher.A.OnEntityAdded(),
Matcher.B.OnEntityAdded()
};
sorry for the inline chat coding
Simon Schmid @sschmid Nov 26 2015 17:33
I usually use MultiReactiveSystem to react on if any of a given set of components were added
public class MySystem : IMultiReactiveSystem
{
public TriggerOnEvent[] triggers {
get
{
return new [] {
CoreMatcher.A.OnEntityAdded(),
CoreMatcher.B.OnEntityAdded()
};
}
}
public void Execute(List<Entity> entities)
{
// entities may contain both, A or B
// since both A or B will act as a trigger
}
}
Maxim Zaks @mzaks Nov 26 2015 19:31
One more gotcha which we avoid with multi reactive system is use of anyOf matcher as a trigger. In my example where we want to validate if an entity has A or B component we might say what about having and Matcher.AnyOf(Matcher.A, Matcher.B).OnEntityAddedRemoved() as a trigger on one system.
Intuitively it feels like a good idea but it is a wrong one. A group which has A or B will be triggered when you will add A or be but it want trigger until you remove A and B. It also wan't trigger if an entity already has A and you just added B, because the entity is already in the group.
This is why my advice is to NEVER use AnyOf matcher as a reactive system trigger. It will feel right but it almost never is
Simon Schmid @sschmid Nov 26 2015 19:55
I was just fooled by this last week myself. I used AnyOf as a trigger in a normal ReactiveSystem. In most cases you should a MultiReactiveSystem for that
I had AnyOf(A, B).
I added A - the system triggered
later I added B - the system didn’t trigger? What? Why?
The entity has already been added to the group when I added A. So when I add B, nothing changes, the Entity is already in the group - no trigger.
That’s why you should use MultiReactiveSystems in this kind of scenario as it will behave as expected
It will trigger when adding A AND when adding B
Jan Thomä @derkork Nov 26 2015 22:57
I see. Well in my case I solved it differently. Basically what I had was an entity which represents a Unit had a GameObject view and a specific MonoBehaviour (a Chronos Timeline) component that i needed to access. So I added a Resource and View component to create the view from a prefab resource just like you did for the match one example (i found that to be a pretty neat way of instanciating views on demand). Now I wanted to have a Timelinecomponent which references the ChronosTimeline from the Unit prefab. Which means I have some kind of dependency here because before I can add the Timeline component, the view has to be created. So I added another component NeedsTimeline which basically works similar to the Resource view. I triggered it using a new system listening toAllOf(View, NeedsTimeline) and then added the actual Timeline component which references the Chronos timeline MonoBehaviour from the now existing view. However this seems a bit too fiddly for my taste. It works but it doesn't feel right.
Jan Thomä @derkork Nov 26 2015 23:02
But I guess I will come up with a set of design patterns over time. A really great thing about Entitas is that - even though it relies on generating code - you can easily refactor anything within the IDE. A lot better than for example UFrame ECS where your code is pretty much broken if you need to refactor anything.