Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Need suggestion about entity relations

Discussion in 'Entity Component System' started by soundeosdev, Feb 7, 2023.

  1. soundeosdev

    soundeosdev

    Joined:
    Dec 24, 2020
    Posts:
    14
    Hi,

    I need a design recommendation for Entity relations. In my game I have cargo items, cities, industries and warehouses. Industries and warehouses belong to cities. Cargo items belong to warehouses. The industries are looking for cargo items. The rule is; industries can only use cargo items from warehouses that are in the same city with them.

    Here is my sample components;

    Code (CSharp):
    1. public struct CargoItem : IComponentData
    2. {
    3.     public FixedString32Bytes name;
    4.     public int amount;
    5. }
    6.  
    7. public struct City : IComponentData{}
    8.  
    9. public struct Warehouse : IComponentData{}
    10.  
    11. public struct Industry : IComponentData{}
    12.  
    13. public struct ItemLocation : IComponentData
    14. {
    15.     public Entity value;
    16. }
    17.  
    18. //The industry entities with this component look for cargo.
    19. public struct LookingForCargo : IComponentData{}
    20.  
    21. //Here are some entities;
    22. //city
    23. var cityA = manager.CreateEntity();
    24. manager.AddComponentData(cityA, new City());
    25.  
    26. //a warehouse belongs to cityA
    27. var warehouseA = manager.CreateEntity();
    28. manager.AddComponentData(warehouseA, new Warehouse());
    29. manager.AddComponentData(warehouseA, new ItemLocation
    30. {
    31.     value = cityA
    32. });
    33.  
    34. //an industry belongs to cityA
    35. var industryA = manager.CreateEntity();
    36. manager.AddComponentData(industryA, new Industry());
    37. manager.AddComponentData(industryA, new ItemLocation
    38. {
    39.     value = cityA
    40. });
    41. manager.AddComponentData(industryA, new LookingForCargo());
    42.  
    43. //some cargo items
    44. var coal = manager.CreateEntity();
    45. manager.AddComponentData(entity, new CargoItem
    46. {
    47.     name = "coal",
    48.     amount = 10
    49. });
    50. manager.AddComponentData(entity, new ItemLocation
    51. {
    52.     value = warehouseA
    53. });
    I need a system that finds all the cargo items that an industry looks for.
    Code (CSharp):
    1. Entities
    2.     .WithAll<LookingForCargo>()
    3.     .ForEach((Entity entity, /* Other components of the industry that define the needed cargo item */) => {
    4.         ...
    5. }).Schedule();
    How can I design this system? Is this the right way to set entity relations?

    Thanks in advance!
     
    Last edited: Feb 7, 2023
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,993
    There's not enough information for us to give you a real answer. Are you concerned about performance, or just making things work? What are the common operations you need to do? How many cities do you have? How many warehouses? How many industries? How many items?
     
  3. soundeosdev

    soundeosdev

    Joined:
    Dec 24, 2020
    Posts:
    14
    Cities can have multiple warehouses and industries. The warehouse count will be less than industrie count, say 2-5 warehouses to 15-20 industiries.
    In the first step, all I want is to access the warehouse content from a system that traverses industries. The next step will be cargo transactions between warehoueses and industries.
     
  4. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,993
    It seems like you would really benefit from a CityOfResidence : ISharedComponentData that applies to industries, warehouses, and items. Then for industries finding items, you can set an EntityQueryFilter on the city to focus on just the items in the same city.
     
  5. soundeosdev

    soundeosdev

    Joined:
    Dec 24, 2020
    Posts:
    14
    What do you think about BufferElements? I added BufferElementData to warehouse and city entities;

    Code (CSharp):
    1. public struct CargoItemList : IBufferElementData
    2. {
    3.     public Entity cargoItem;  
    4. }
    5.  
    6. public struct CityWarehouseList : IBufferElementData
    7. {
    8.     public Entity warehouse;
    9. }
    When I create a new warehouse entity, I also add it to the CityWarehouseList of the city entity. Same thing with the CargoItem entities. And in the system I can find the related items like this;

    Code (CSharp):
    1. var cargoItemLists = GetBufferFromEntity<CargoItemList>(false);
    2. var cityWarehouseLists = GetBufferFromEntity<CityWarehouseList>(true);
    3. var cargoItems = GetComponentDataFromEntity<CargoItem>(true);
    4.  
    5. Entities
    6.     .WithAll<LookingForCargo>()
    7.     .ForEach((Entity entity, in ItemLocation itemLocation) => {
    8.         var cityEntity = itemLocation.value;
    9.         var cityWarehouses = cityWarehouseLists[cityEntity];
    10.         for (int i = 0; i < cityWarehouses.Length; i++)
    11.         {
    12.             var warehouseEntity = cityWarehouses[i].warehouse;
    13.             var warehouseCargoItems = cargoItemLists[warehouseEntity];
    14.             for (int j = warehouseCargoItems.Length - 1; j >= 0 ; j--)
    15.             {
    16.                 var cargoItemEntity = warehouseCargoItems[j].cargoItem;
    17.                 var cargoItem = cargoItems[cargoItemEntity];
    18.                 ...
    19.             }
    20.         }
    21. }).Schedule();
    This seems complicated though.
     
  6. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    801
    Really hard to say without knowing everything about our game. Does each item have a mesh assigned to it?

    Per city tags may also be a option.
     
  7. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,993
    You can structure the data however you want if it works for you. But I can tell you right now that iterating cargo via an EntityQuery rather than a dynamic buffer is going to be a lot faster.
     
  8. soundeosdev

    soundeosdev

    Joined:
    Dec 24, 2020
    Posts:
    14
    Only cities have a mesh.
     
  9. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    801
    If that is the case then you don't need to be using entities at all. Make some custom data structure and associate that data with your city entity.
     
    Last edited: Feb 10, 2023