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. Dismiss Notice

Question Issue spawning entities

Discussion in 'Entity Component System' started by Steff00212, Aug 12, 2023.

  1. Steff00212

    Steff00212

    Joined:
    May 17, 2013
    Posts:
    14
    Hey guys. I am trying to spawn a lot of entities and move them down by deltaTime. There are entites in the entity hierarchy, but the only entity being rendered is the one that's already present in the scene hierarchy on startup.
    This is my SpawningSystem:

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Mathematics;
    3. using Unity.Transforms;
    4.  
    5. public partial class AgentSpawningSystem : SystemBase
    6. {
    7.     protected override void OnStartRunning()
    8.     {
    9.  
    10.         AgentSpawnSettings settings = SystemAPI.GetSingleton<AgentSpawnSettings>();
    11.         Entity agent = EntityManager.GetComponentData<MovementAgent>(SystemAPI.GetSingletonEntity<MovementAgent>()).Prefab;
    12.  
    13.         Random rnd = new Random();
    14.         rnd.InitState(49600);
    15.  
    16.         for (int i = 0; i < settings.SpawnAmount; i++)
    17.         {
    18.             float3 rndPos = rnd.NextFloat3(settings.MinPos, settings.MaxPos);
    19.  
    20.             LocalTransform localTransform = new LocalTransform
    21.             {
    22.                 Position = rndPos
    23.             };
    24.             Entity spawnEntity = EntityManager.Instantiate(agent);
    25.             EntityManager.SetComponentData(spawnEntity, localTransform);
    26.         }
    27.     }
    28.    
    29.     protected override void OnUpdate()
    30.     {
    31.  
    32.     }
    33. }
    34.  
    This script is attached to the agent prefab in the scene hierarchy:

    Code (CSharp):
    1. using Unity.Entities;
    2. using UnityEngine;
    3.  
    4. public class SpawnedAgent : MonoBehaviour
    5. {
    6.     public GameObject Prefab;
    7. }
    8.  
    9. public class BakeMovementAgent : Baker<SpawnedAgent>
    10. {
    11.     public override void Bake(SpawnedAgent authoring)
    12.     {
    13.         Entity entity = GetEntity(TransformUsageFlags.Dynamic);
    14.         Entity prefabEntity = GetEntity(authoring.Prefab, TransformUsageFlags.Renderable);
    15.         AddComponent(entity, new MovementAgent
    16.         {
    17.             Prefab = prefabEntity
    18.         });
    19.     }
    20. }
    21.  
    22.  
    This is my component data:

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Mathematics;
    3.  
    4. public struct MovementAgent : IComponentData
    5. {
    6.     public Entity Prefab;
    7. }
    8.  
    9. public struct AgentFlag : IComponentData
    10. {
    11.  
    12. }
    13. public struct AgentSpawnSettings : IComponentData
    14. {
    15.     public int SpawnAmount;
    16.     public float3 MinPos;
    17.     public float3 MaxPos;
    18. }
    This is what my scene hierarchy looks like:
    upload_2023-8-12_18-28-55.png

    This is my entity hierarchy:
    upload_2023-8-12_18-31-47.png
    (As you can see, the entities are instantiated)

    This is what it looks like in the scene:
    upload_2023-8-12_18-32-37.png

    If I click on any of the entities, this entity is highlighted. But all the entities have different positions. Very weird to me.

    Appreciate any help!
     

    Attached Files:

  2. Spy-Master

    Spy-Master

    Joined:
    Aug 4, 2022
    Posts:
    282
    You did not initialize the LocalTransform correctly. You did not specify a rotation or scale, which means they will default to 0 as will happen when struct members are not initialized in the object initializer (when the default constructor is used). A quarternion of 0’s is invalid, and a scale of 0 is obviously not correct. You need to set the rotation to something valid like quaternion.identity and the scale to a correct value. You can also use some of the static methods to create valid LocalTransform here.
    https://docs.unity3d.com/Packages/com.unity.entities@1.0/api/Unity.Transforms.LocalTransform.html
     
  3. Steff00212

    Steff00212

    Joined:
    May 17, 2013
    Posts:
    14
    I changed the for loop to this:
    Code (CSharp):
    1.         for (int i = 0; i < settings.SpawnAmount; i++)
    2.         {
    3.             float3 rndPos = rnd.NextFloat3(settings.MinPos, settings.MaxPos);
    4.  
    5.             LocalTransform localTransform = LocalTransform.FromPosition(rndPos);
    6.  
    7.             Entity spawnEntity = EntityManager.Instantiate(agent);
    8.             EntityManager.SetComponentData(spawnEntity, localTransform);
    9.         }
    Still the same result as before.
     
  4. Tigrian

    Tigrian

    Joined:
    Mar 21, 2021
    Posts:
    105
    Your agents probably don't have a localTransform component, because you set the transformUsageFlag to renderable (only a localToWorld) on your agent entity prefab
     
  5. Steff00212

    Steff00212

    Joined:
    May 17, 2013
    Posts:
    14
    Added the component:
    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Mathematics;
    3. using Unity.Transforms;
    4.  
    5. public partial class AgentSpawningSystem : SystemBase
    6. {
    7.     protected override void OnStartRunning()
    8.     {
    9.  
    10.         AgentSpawnSettings settings = SystemAPI.GetSingleton<AgentSpawnSettings>();
    11.         Entity agent = EntityManager.GetComponentData<MovementAgent>(SystemAPI.GetSingletonEntity<MovementAgent>()).Prefab;
    12.  
    13.         Random rnd = new();
    14.         rnd.InitState(49600);
    15.  
    16.         for (int i = 0; i < settings.SpawnAmount; i++)
    17.         {
    18.             float3 rndPos = rnd.NextFloat3(settings.MinPos, settings.MaxPos);
    19.  
    20.             LocalTransform localTransform = LocalTransform.FromPosition(rndPos);
    21.  
    22.             Entity spawnEntity = EntityManager.Instantiate(agent);
    23.             EntityManager.AddComponent<LocalTransform>(spawnEntity);
    24.             EntityManager.SetComponentData(spawnEntity, localTransform);
    25.         }
    26.     }
    27.    
    28.     protected override void OnUpdate()
    29.     {
    30.  
    31.     }
    32. }
    33.  
    Still doesn't work.
     
  6. Tigrian

    Tigrian

    Joined:
    Mar 21, 2021
    Posts:
    105
    Hum, it should work in that case. Or at least i don't see the problem. And you are saying that all entities have different position? In that case, i suppose it is a problem with the rendering, check the RenderMeshArray, the RenderMesh and RenderBounds components, see if there is a problem there.

    I'll try your code on my machine as soon as i get home.
     
  7. Tigrian

    Tigrian

    Joined:
    Mar 21, 2021
    Posts:
    105
    I've tried to reproduce your code, and there is something i don't understand. It works on my side, but all the instantiated entities are not prefabs, just instantiated entities (they don't have the blue icon in entity hierarchy), so definitely not what you get in your image. Are you on the last version of entities?
     
  8. Steff00212

    Steff00212

    Joined:
    May 17, 2013
    Posts:
    14
    Maybe because you're missing the settings object. I created an empty object in the scene hierarchy, and added this script:

    Code (CSharp):
    1. using Unity.Entities;
    2. using UnityEngine;
    3.  
    4. public class AgentSettings : MonoBehaviour
    5. {
    6.     public Vector3 MinPos;
    7.     public Vector3 MaxPos;
    8.     public int SpawnCount;
    9.  
    10.     private void OnDrawGizmos()
    11.     {
    12.         Gizmos.color = Color.yellow;
    13.         Gizmos.DrawWireSphere(MinPos, 1f);
    14.         Gizmos.DrawWireSphere(MaxPos, 1f);
    15.     }
    16. }
    17.  
    18. public class BakeAgentSettings : Baker<AgentSettings>
    19. {
    20.     public override void Bake(AgentSettings authoring)
    21.     {
    22.         Entity entity = GetEntity(TransformUsageFlags.Dynamic);
    23.         AddComponent(entity, new AgentSpawnSettings
    24.         {
    25.             SpawnAmount = authoring.SpawnCount,
    26.             MinPos = authoring.MinPos,
    27.             MaxPos = authoring.MaxPos,
    28.         });
    29.     }
    30. }
    Then I selected the "Agent" object from the scene hierarchy as Prefab, see screenshot below:

    upload_2023-8-14_0-58-35.png
     
  9. Steff00212

    Steff00212

    Joined:
    May 17, 2013
    Posts:
    14
    And yes, all entities have different positions, and I am on the latest version of entities.
     
  10. Steff00212

    Steff00212

    Joined:
    May 17, 2013
    Posts:
    14
    Also, all entities seem to reference the initial "Agent" prefab. Every time I click on one, the initial prefab is highlighted. But they all have different positions in the inspector.
     
  11. Tigrian

    Tigrian

    Joined:
    Mar 21, 2021
    Posts:
    105
    No, I did not miss the settings object. My cubes spawned with your scripts, thus my wonder. Do you reference the agent gameobject in your subscene or the actual prefab in asset folder?
     
  12. Tigrian

    Tigrian

    Joined:
    Mar 21, 2021
    Posts:
    105
    Capture 2.PNG Capture1.PNG My results (I'm in 3D). The only thing I changed from your scripts is that I added an OnCreate in the system, to RequireForUpdate the singletons, otherwise I was just getting "singleton query must be one but found 0" type errors. All the rest is from you. Does the agent have anything else as component other than the render components?
     
  13. Steff00212

    Steff00212

    Joined:
    May 17, 2013
    Posts:
    14
    I reference the agent gameobject in the subscene.
     
  14. Steff00212

    Steff00212

    Joined:
    May 17, 2013
    Posts:
    14
    This:
    upload_2023-8-14_18-32-53.png
    Is the output of this: (Which I added to the SpawningSystem)

    Code (CSharp):
    1.         int counter = 0;
    2.         foreach ((LocalTransform tranform,Entity entity) in SystemAPI.Query<LocalTransform>().WithEntityAccess())
    3.         {
    4.             NativeArray<ComponentType> arr = EntityManager.GetComponentTypes(entity);
    5.             foreach (var item in arr)
    6.             {
    7.                 Debug.Log(item);
    8.             }
    9.             if(counter >= 5) break;
    10.             counter++;
    11.         }
     

    Attached Files:

  15. Steff00212

    Steff00212

    Joined:
    May 17, 2013
    Posts:
    14
    I removed the prefab the object in the scene referenced and just added the agent to the scene without prefab. They spawn now. What the heck?
     
  16. Tigrian

    Tigrian

    Joined:
    Mar 21, 2021
    Posts:
    105
    Ah, you have a companion link! I've not done any 2d or ui, so i did not know that unity puts a companion link on every sprite renderer converted entities. So i've tested with a sprite renderer instead of mesh filter+mesh renderer, and what i get is still different of your image. In the setup of agent prefab gameobject put directly in subscene, and reference as gameobject in subscene and not external prefab (what you had in the beginning), i just get that the entities spawn at random position, but for some reason, the companion gameobject is not in the hierarchy or rendering (but it exists, as the companion link field shows), they are not blue prefabs icons though, so it is not exactly like you. And whatever the way I try (referencing the agent as non prefab, or referencing directly the prefab), the sprites don't render. I'm curious now. What exactly have you done do unlock the rendering? What are you referencing in the agent prefab field in the SpawnedAgent authoring?
     
  17. Steff00212

    Steff00212

    Joined:
    May 17, 2013
    Posts:
    14
    They were grey icons after I got it running:
    upload_2023-8-15_2-34-36.png
    I simply deleted the prefab in the assets (So it doesn't exist in the file explorer) and added the agent to the scene without being a prefab:
    upload_2023-8-15_2-35-57.png
    This agent is what I am referencing as prefab.

    But there's another issue I am running into now :D When trying to move them in the Entities.ForEach loop, using .Run(), .Schedule(). and ScheduleParallel() all have the same performance o_O
    Do you know what could cause that? If so, code below, if not, I still have to thank you so much for investing so much time helping me fix my problems! :)

    Here's my AgentMoveSystem:
    Code (CSharp):
    1. using Unity.Collections;
    2. using Unity.Core;
    3. using Unity.Entities;
    4. using Unity.Mathematics;
    5. using Unity.Transforms;
    6.  
    7. public partial class AgentMoveSystem : SystemBase
    8. {
    9.     protected override void OnUpdate()
    10.     {
    11.  
    12.         float deltaTime = World.Time.DeltaTime;
    13.         Random rnd = new Random();
    14.         rnd.InitState(49500);
    15.  
    16.  
    17.         AgentSpawnSettings settings = EntityManager.GetComponentData<AgentSpawnSettings>(SystemAPI.GetSingletonEntity<AgentSpawnSettings>());
    18.  
    19.         float3 minPos = settings.MinPos;
    20.         float3 maxPos = settings.MaxPos;
    21.  
    22.         Entities
    23.             .ForEach((ref MovementAgent agent, ref LocalTransform localTransform) =>
    24.             {
    25.  
    26.                 localTransform.Position =
    27.                 new float3(localTransform.Position.x + rnd.NextFloat(), localTransform.Position.y + rnd.NextFloat(), localTransform.Position.z);
    28.  
    29.                 if (localTransform.Position.y < minPos.y) localTransform.Position =
    30.                     new float3(localTransform.Position.x, maxPos.y, localTransform.Position.z);
    31.  
    32.                 if (localTransform.Position.y > maxPos.y) localTransform.Position =
    33.                     new float3(localTransform.Position.x, minPos.y, localTransform.Position.z);
    34.  
    35.                 if (localTransform.Position.x < minPos.x) localTransform.Position =
    36.                     new float3(maxPos.x, localTransform.Position.y, localTransform.Position.z);
    37.  
    38.                 if (localTransform.Position.x > maxPos.x) localTransform.Position =
    39.                     new float3(minPos.x, localTransform.Position.y, localTransform.Position.z);
    40.  
    41.  
    42.             }).ScheduleParallel();
    43.     }
    44. }
     
  18. Tigrian

    Tigrian

    Joined:
    Mar 21, 2021
    Posts:
    105
    I can not be sure about why you have no performance difference between the scheduling mode, but I have seen you started an other thread, and that you are in good hands:). I'll let you see how to find the why in the other thread.