sschmid / Entitas

Entitas is a super fast Entity Component System (ECS) Framework specifically made for C# and Unity
MIT License
7.02k stars 1.11k forks source link

Is it allowed that if the component has an array or list or dictionary? #452

Closed colourstar closed 6 years ago

colourstar commented 6 years ago

I have a question about the ecs framework,if i want to implement a system that collect all player's input into a list cache,and do diffrent things depend on these diffrent input information in the list cache,most important,by order,how can i design this component and the system? Or when i design a game,there are some players,every player has some skills,and each skill has some effects,how can i design this componets and systems?Is it allowed that if the component has an array or list or dictionary? thanks a lot!

FNGgames commented 6 years ago

Collections in components are fine. You can access them and modify them as you would normally. The only trick is that you should use the .Replace() method after you're done modifying the collection to ensure that the rest of your code can react to the change.

e.g.

// component definition (int is just for example, list could be any collection)
[Game] 
public class MyListComponent : IComponent {
    public List<int> values;
}

// usage (no copying or new collection created, no memalloc)
var myList = entity.myList.values; // access
myList.Add(1); // modification
entity.ReplaceMyList(myList); // update

in many cases however, you might prefer to have a separate entity for each element, in which case you could do sth like this:

// component definition (int is just for example)
[Game] 
public class MyItemComponent : IComponent {
    public int value;
}

// usuage (grab all entities with myItem component and do sth)
IGroup<GameEntity> myItemEntities = context.GetGroup(GameMatcher.MyItem); // access
// up-to-date array of entities with myItemComponent
foreach (var item in myItemEntities.GetEntities()) {
    // do sth
}
Gasskin commented 1 year ago

Collections in components are fine. You can access them and modify them as you would normally. The only trick is that you should use the .Replace() method after you're done modifying the collection to ensure that the rest of your code can react to the change.

e.g.

// component definition (int is just for example, list could be any collection)
[Game] 
public class MyListComponent : IComponent {
    public List<int> values;
}

// usage (no copying or new collection created, no memalloc)
var myList = entity.myList.values; // access
myList.Add(1); // modification
entity.ReplaceMyList(myList); // update

in many cases however, you might prefer to have a separate entity for each element, in which case you could do sth like this:

// component definition (int is just for example)
[Game] 
public class MyItemComponent : IComponent {
    public int value;
}

// usuage (grab all entities with myItem component and do sth)
IGroup<GameEntity> myItemEntities = context.GetGroup(GameMatcher.MyItem); // access
// up-to-date array of entities with myItemComponent
foreach (var item in myItemEntities.GetEntities()) {
    // do sth
}

but in this case, how do i distinguish which entity these items belong to? for example,if i have 2 hero entity, every hero has a lot items, i can create Item Entity and add ItemComponent for each item, but how to know hero1 contains which items?only i can do is,add a heroId property in ItemComponent..but its may be a little strange...?