Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Using ECS with Nested Gameobjects,

Discussion in 'Data Oriented Technology Stack' started by Shabbalaka, Jan 21, 2020.

  1. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    Hi,

    I am using the RPGHero Free from the asset store as a test, and then when I use a ConverToEntity component It converts it to an entity but it looks like it seperates every single bone and piece of the model into an entity ?

    If you look at the image that,s what ConvertToEntity returned to me, How am I supposed to use that??

    Is there a way to make it so it works like the editor view?

    All of the tutorials I watch and stuff use very simple prefabs like with 1 item on them to convert to entity which in a real scenario I would imagine you would have multiple objects within a prefab (A house would have windows, doors and walls for example)

    Or should I forget about using ECS for nested models?

    Hope someone can clear this up for me I have been trying for AGES to work out how this ECS would work with nested models, Or if someone can point me to a good tutorial which uses nested models I would appreciate it!

    Many Thanks!
     

    Attached Files:

  2. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    518
    Unfortunately the entity debugger will only show a non hierachical view of all entities but it will show if they have a parent or child relationship which you can actually click through to follow now.
    In case you dont want the entire hierarchy converted there is also the "Stop" component you can add to do this. Best to use specific components to filter your results if you need to find something specific as I doubt any changes will be happening soon on this area.
     
    Last edited: Jan 22, 2020
  3. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    Many thanks for the reply,

    Sorry if im not fully understanding, So I should add a "tag" component to the root object and then if i use this tag to identify this Gameobject in the Entity World?

    Code (CSharp):
    1. public struct KnightTag : IComponentData
    2. {
    3. }
    and then apply this to each converted piece of the model as the model has animations associated with it also.

    I think this is very difficult to use currently for prefabs which are more than 1 full object (So i think I will need to use a full model whiich is the full model and not in parts if I want to use ECS)

    I made a very crude tank Prefab using 3 cubes and 1 sphere inside an empty Gameobject called Tank then converted this to a 100 x 100 square of entities and it still results in 50,000 and not the 100 x 100 but if I create the same Tank model in Blender as a Single Model with no hierarchial gameobjects it creates 10,000 entities, This causes an issue if say I want to move the Turret on the tank to face a different direction??

    Would I need to have 1 Model for the Tracks of the tank, another for the Tank Body, another for the Tank Cannon and Turret Base and another for the viewing dome on top??

    Then apply blank tags to each of the "sections" so I can reference them in the Systems?

    Tag : Turret, TankBody, TankTracks??

    Then use a for each TurretBase and Cannon and then rotate the turret base and turret indivually??

    Sorry if im rambling just that this has me completely baffled and either this is not possible or it,s not really valid to do in ECS atm which would explain why there is no tutorials at all using Nested Gameobjects in ECS.(Or i cannot find one)
     
    Last edited: Jan 22, 2020
  4. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    I guess this is still a limitation of ECS and which is why some things are good for ECS like single model objects (Projectiles, Single Model Objects such a grass, trees, and other things and anything which contains only a single model with no other "children")

    I think I will use Gameobjects if I want to use a complex model which has a multitude of children gameobjects as it gets VERY messy in ECS to access Children gameobjects as shown above.

    Unless I am missiing something very vital but I have found very little information regarding this.

    Does this mean that if I manage to find the "parent" entity I can reference that entity say for example it has a Component Named Player I can do a
    Entities.ForEach ((ref PlayerTag playertag) =>{ Do something with the playerTag and all of the children components?});

    So if i moved the entity with playerTag on it would this also move all the sub-entitys of the root entity??
     
  5. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    Ok thought I would add an update to this as I think I finally figured it out or worked it out.

    I created an empty GameObject then made children and added a ConvertToEntity Component to the Parent (Root) object (See Image)

    1: I placed this code on a script which allowed me to drag it onto the root object of our GameObject hierarachy.
    Code (CSharp):
    1. using Unity.Entities;
    2.  
    3. [GenerateAuthoringComponent]
    4. public struct PlayerRootComponent : IComponentData
    5. {
    6.  
    7. }
    2: I then created a component like so again this was draggable onto the root GameObject.
    Code (CSharp):
    1. using Unity.Entities;
    2.  
    3. [GenerateAuthoringComponent]
    4. public struct PlayerRotator : IComponentData
    5. {
    6.     public float RotateSpeed;
    7.  
    8.     public float Rotation;
    9.  
    10. }
    11.  
    3: I then accessed these components in the system below.
    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Entities;
    3. using Unity.Transforms;
    4. using Unity.Mathematics;
    5.  
    6. /// <summary>
    7. /// Rotator system.
    8. /// This system grabs all Rotators and rotate them.
    9. /// </summary>
    10. public class RotatorSystem : ComponentSystem
    11. {
    12.     protected override void OnUpdate()
    13.     {
    14.         // Grabs all entities with Rotator,Rotation and PlayerRootComponent components attached to them.
    15.         Entities.ForEach((ref PlayerRotator rotator, ref PlayerRootComponent rootComponent, ref Rotation rotation) =>
    16.         {
    17.             // Updating rotation.
    18.             rotator.Rotation += rotator.RotateSpeed * Time.DeltaTime;
    19.             // Assigning new rotation in Rotation Component (equivalent to Transform.rotation)
    20.             rotation.Value = quaternion.RotateY(rotator.Rotation);
    21.         });
    22.     }
    23. }
    This allowed me to rotate a object with 2 children and I could very well rotate a Gameobject with 100 children.

    I hope this helps anyone else who is struggling how to access a Root GameObject in a ConvertToEntity scenario.

    If there is anything important that I missed please let me know as I am still learning ECS and this may not be optimal or "good practice".

    Time to move onto Animaton and try to work out why imported models from the asset give the errors of A Component of Type BoneIndexOffset jhas not been added to the entity.



    Thanks!
     

    Attached Files:

    Last edited: Jan 25, 2020
  6. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    518
    Glad its making more sense. You can also access child entities via dynamic buffer https://docs.unity3d.com/Packages/com.unity.entities@0.5/api/Unity.Transforms.Child.html?q=child
    Its a bummer that there's no way to organize the debugger and it doesn't show that transform hierarchies in a way that makes sense but thats the price of being an early adopter.
    For the animation error I believe its due to not having the animation package in your manifest(its hidden in the package manager)
    Code (CSharp):
    1. "com.unity.animation": "0.2.16-preview.5",
    theres a repo with more examples, though they say its subject to change
    https://github.com/Unity-Technologies/Unity.Animation.Samples/tree/master/UnityAnimationHDRPExamples
     
  7. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    Ok i had a thought of trying this

    I added a BoneOffsetIndex empty component and removed the Animator Controller so I guess the Animator Controller is not causing the BoneOffsetIndex error as shown below.

    Will have to research some more as to as of current the free unity 3d models are unusable in ECS for me so I am dubious to buy some models to use in until I figure out this error.

    I checked out the FPS sample from Unity example but there is so much packages and its like finding a needle in a haystack to try and reverse engineer what they have coded.

    Also when I went to the Package Manager and searched for Animation it only gave me 2dAnimation as a possible pacakge?

    Imported the animation package by pasting your string into the maniefest.json and I still receive this boneindex error.

    Many thanks for the reply!
     

    Attached Files:

    Last edited: Jan 25, 2020
  8. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    Just in case anyone is wondering I am still having no joy with the Animation package and the how to use it guide on Github is a bit confusing to understand.

    If anyone has any good information or basic tutorials I can follow for the Animation in ECS it would be appreciated!

    Many Thanks!
     
  9. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,015
    II am wondering how it worked out for you. It seems I can make a great deal of the subatomic particle sims that have been causing crashed and I ca't have too many of these rigidbodies at once without hiccups,,so I am definitely thinking about using this DOTS tech but I am worried about further death by a further thousand cuts due to not enough answers around about converting complex hierarchical character animations or complex physics..or frankly whether I have to. How has working with both gameObjects and entities been working out for you?
     
  10. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    I will try adding Rigidbodies and Collides and get back to you. ;)
     
  11. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,015
    I just got rigidbodies falling..now to tag my environment and then spawn them.
     
  12. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    How did you get on with the rigidbodies and stuff, I got the rigidbodys(Physics Body) and Physics Shapes to spawn just sorting out the ground for them to bounce now.
     
  13. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,015
    I struggled trying to get an ECS styled spawner right. If I can figure out the pattern and which type of objects and types can go in each and whether I need all three ECS types to be present when i want to code something.

    Alot of examples are from older builds and of course..the simple things I want to do are skirted by every example. How the heck do i trigger ECS spawning from a monobehaviour. I have several rigidbody emitters. They all did essentially the same thing..wait for a bool to hit true, emit rigidbodies at such and such an interval till it changed back to false. The other thing baffling me is how trigger events get passed to mono. I have to design these so that a designer has access to all the variables to design gameplay. He was doing great balancing with the monobehavior components and Inspector. Seems I cannot move quickly ahead with either system. Physx rigidbodies with particle systems still crashing me to desktop..They really need to design access to ECS to be much more friendly than it is. I can and have written monobehaviour rigidbody spawners with all the bells and whistle in like 10 or 15 minutes max. I spent like 14 hours coding and then recoding then recoding ..always some BS. I may have something that will lead to what I need today based on that. But my brain still hurts..LOL

    I also noticed that unity physics has some nasty bounces on flat surfaces when they meet an edge of a poly..not all..just particular places. Switching to Havok sim the massive bounces off a flat floor disappeared.
     
  14. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    Im not sure if this will help but its a topic I started a while back and it,s about my learning ECS systems I would hope theres some useful information there.


    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using Unity.Entities;
    6. using Unity.Collections;
    7. using Unity.Rendering;
    8. using Unity.Transforms;
    9. /*
    10. Packages
    11. Collections
    12. Hybrid Renderer
    13. Entities
    14. */
    15.  
    16.  
    17. public struct HealthComponent : IComponentData {
    18.     public float Value;
    19. }
    20.  
    21. public class EntityClone : MonoBehaviour
    22. {
    23.  
    24.     [SerializeField]
    25.     public Mesh mesh;
    26.  
    27.     [SerializeField]
    28.     public Material material;
    29.  
    30.       private EntityManager em;
    31.  
    32.       public int NumToCreate;
    33.  
    34.       public float Spacing;
    35.  
    36.     public void Start()
    37.     {
    38.  
    39.         em = World.DefaultGameObjectInjectionWorld.EntityManager;
    40.  
    41.         EntityArchetype ea = em.CreateArchetype(
    42.             typeof (Translation),
    43.             typeof (LocalToWorld),
    44.             typeof (HealthComponent),
    45.             typeof (RenderMesh)
    46.      
    47.         );
    48.         NativeArray<Entity> entityArray = new NativeArray<Entity>(NumToCreate, Allocator.Temp);
    49.         em.CreateEntity(ea, entityArray);
    50.         for(int i = 0; i < entityArray.Length; i++)
    51.         {
    52.          
    53.             Entity entity = entityArray[i];
    54.  
    55.             em.SetComponentData(entity, new HealthComponent { Value = Random.Range(0f,1000f)});
    56.             em.SetSharedComponentData(entity, new RenderMesh {
    57.              
    58.                 mesh = mesh,
    59.                 material = material
    60.  
    61.             });
    62.             em.SetComponentData(entity, new Translation{Value = new Unity.Mathematics.float3(Spacing * i,Spacing * i,Spacing * i) });
    63.         }
    64.  
    65.         //Clean up the array as we do not need to keep it in memeory anymore.
    66.         entityArray.Dispose();
    67.     }
    68. }
    69. }

    https://forum.unity.com/threads/ecs-advice.751301/page-2#post-5157596

    The above code allows you to drag a mesh and material and set the number of entities you want to spawn You can change the Random Position thing.

    The main problem I have with ECS is trying to get my head round the fact that they are NOT Objects and how you can single out a reference (I know you can use an empty Component within the Entity itself and do Entities.ForEach((ref PlayerTag tag) => )
     
    Last edited: Jan 30, 2020
    Morvar and ippdev like this.
  15. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,015
    That most certainly helps. It is very close to what I am trying to do wen spawning. I have the same issue as you. If I collide with one of these as a pickup before I would just do a tag compare and score appropritely, add buffs to the vehicle power, reduce damage, ad score to UI. But I can't even make a public field to accept these components and objects to talk to like they are a different game engine altogether....and I ain't thrilled about tuning up a rigidbody monowheel stick to the walls vehicle with local gravity and a PID controller to stabilize it.. It took a few weeks to balance effectively for drifting, steering velocity and I do not see any equivalents to set it up like so in ECS-DOTS.Now I could effectively have some follow colliders that are ECS-DOTS physics..bet even something simple like putting an entity at such and such a location at such and such rotation is not a simple equivalency line of code..entity.transform.position = vehicle.transform.position. All I can say is ouch! Again. Thanks for giving me something I can actually break down, understand and possibly put to use.
     
  16. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    Thankfully from my experience with ECS, If you want to modify a component in an Entity you do it through a System

    Code (CSharp):
    1.  
    2. public class MoveSpeedSystem : ComponentSystem
    3. {
    4.  
    5.     public float MoveSpeed= 5f;
    6.  
    7.    protected override void OnUpdate()
    8.    {
    9.        //For every entity which has a Translation component
    10.        Entities.ForEach( (ref Translation position) =>
    11.        {
    12.            //Get the delta time from Unity.
    13.            var deltaTime = Time.DeltaTime;
    14.            // Move all entitys with the above components along the X axis by the movespeed.
    15.            position.Value = new float3(MoveSpeed * deltaTime,0f,0f);
    16.  
    17.      
    18.        });
    19.    }
    20. }
    I like to think of OnUpdate as this is outside of ECS and gives us access to the normal functions such as Transform and such.

    Transform = Translation so whenever you ConvertToEntity it will automatically get given a Translation component.

    I think the system above works but i havent tested it.

    I read your other post on my other thread, The hardest thing to remember is that ECS Scripts do not need a object and they will run just by sitting in your project folder, So you do not need to attach the above script to any GameObject for it to work, Sorry if I am explaining too much of what I learnt so far and you may already know, Just trying to give you as much info as I can and in the end maybe we can help each other on this bumpy road of ECS lol

    I am currently at a point where I am trying to write a large scale battle thing, I have the "armies" spawning and now need to work out how to use AnimatorControllers in ECS (Which there is no tutorials of atm or I cant find any). After all it,s no good if they walk towards each other but cant attack when in range. xD
     
    Last edited: Jan 30, 2020
    ippdev likes this.
  17. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,015
    Thanks for the further script. I got nearly that far yesterday about 8 hours in as far as understanding how and where to do some things. Then wrote some code that started giving me problems, took all 12 scripts I had built as entity and component and system and deleted them to start from scratch and wanted to be sure what every step was doing. I am enjoying the other thread because you have the same thinking processes and training. I am not a comp sci guy. I am a nerd artist scientist musician industrial designer that likes working in interactive 3D environments and enjoy a good puzzle which any complex application code is. I consider myself more of a hot rod mechanic than a factory trained technician. I am going to go back to the other thread and finish it. The take these two sample you posted and give it another run. I am trying to figure out how to get my own drag and drop collision detection and trigger detection ECS scripts going so they can just send collision data in the same format to my scripts that have an OnCollisionDetected(Collision collision) {//get tag, contact point for efx instantiation, callback to destroy gameObject}

    The other big thing is particle system. They just hung in air and did not follow the entities. Mind you the mysterious constant crashes to desktop within 30 seconds of hitting Play are what drove me to ECS to try to get a rigidbody system going that would not crash as it has been doing from 2019.3-2019.6. Prior to that I had 9 complex levels created and most of the 250+ assets from scratch and a 300 script codebase and started it second week of December 2019. So..it was crashing from either rigidbodies made active and given velocity with AddRelativeForce, rigidbodies made active with particle systems or particle systems that have Size module activated..or all three..it still isn't fixed as of latest drop. So, I was thinking one of my bottlenecks may be the particle trails, but I am simulating subatomic particles and to see where they go you need a trail renderer and the particles left a nice ring every frame which can be reproduced with a sprite.. But then my head breaks trying to determine where to insert calls to a line renderer and a sprite instantiator when I can't have anything but blittable types in the only component it lets me attach to a game object.

    So I think the future of DOTS lies in it substituting for bulletstorm type systems or huge dynamic inventories being moved around in game, mob battles and the like. But all of these depend heavily on UI, particleSystem efx and standard Unity GameObjects. Trying to find a particular entity in Scene view has been impossible if I do not know where it is because it is bouncing around..maybe.. Unity is usually pretty good at making things friendly to tech oriented designer without the comp sci degrees. Hopefully they can pull off some magic in regards to making this friendlier. 400 lines of code for a simple mousepick and throw is not acceptable when it can be done in a monobehaviour in less than 20 lines. The other thing is that many of us use this app to make a living..often on fixed price contracts. Clients wants an ECS physics system..and he wants something similar to a mousepick throw but diff enough a simple cut and paste don't work. Instead of spending ten minutes and optimizing the dollars I make an hour i now take a pay cut because even if I know what i am doing I am writing a story instead of a few sentences.
     
  18. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,015
    And dang it works dandy. I think your trick here is passing in a mesh and material. Did not see that approach in the hundreds of boilerplate examples I have reviewed this week. And it works in the Inspector..WOOT! Ten years staring at that sucker is not an easy habit to break and frankly it is why I was able to get a grip on Unity so rapidly. Going to alter it a bit and see what I can do about attaching rigidbodies and get them into the physics sim world. Your code looks a hellofalot more like Unity boilerplate than all the other cruft I have had to sift thru to make sense out of this. So I can make some headway. Thanks a million pal! I think Unity tech oughta waddle their butts over to Unity art and designer section, plop their code down and ask them to do something with it so they get a feel for what at least half of the demographic is thinking. Your other thread was awesome and a good read for folks finding their way thru this.
     
  19. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,015
    I saw somewhere in my reading that you sample two frames at a time and feed that back into the entity.. How? I don't frikkin' know :) On the above script..yes, that type of code was working for me yesterday. So of course you are not going to move every entity so you have to add other components that distinguish them for targeting. For example I have three main rigidbody types that are involved everywhere. A Proton, a Neutron and an Electron. They of course have rules for interaction with same type and the others as well as special parameters and values they impart upon collision with the probe vehicle. So I think I make an AtomicSpeciesData component that has all their blittable values on them and an enum for the type of species it is. I can then iterate thru the entities to extract only those whose AtomicSpeciesType enum is for example an Electron type. Let me give it a go and I will report back..sooner or later..LOL.
     
  20. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    I think I got that code from a tutorial from Code Monkey on Youtube he has tonnes of ECS Tutorials which are very good and most of the older ones are still relevant now, I modified it slightly to make it into a template.

    I would recommend him as that,s where I am picking up most of my knowledge from! : )
     
    nicolasgramlich likes this.
  21. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,015
    I have watched a bunch of his. I am doing better with the the sample and have physic components being attached as well as the AtomicSpeciesData component so I have access to all those numbers and enums for any species to species interaction when I get down the road. I complain but this is the way to go or Unity cannot calculate attraction and repulsion with inverse square falloffs without killing the mono systems framerate..so onward. I have been trying to get the collision shapes onto the entity. I have the PhysicsCollider component attached but when attached it only gives me a Value to use in SetComponentData. Thinking about it and peeking at the definition it may be the Value is the index to the type of collider..but it should have a better name than Value if so..like ColliderTypeIndex. When I added the Physics package it made Material ambiguous so I had to specify UnityEngine.Material..but so far good to go.. Here is the modifications so far.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.Entities;
    5. using Unity.Collections;
    6. using Unity.Rendering;
    7. using Unity.Transforms;
    8. using Unity.Physics;
    9. /*
    10. Packages
    11. Collections
    12. Hybrid Renderer
    13. Entities
    14. */
    15.  
    16.  
    17. public struct HealthComponent : IComponentData {
    18.     public float Value;
    19. }
    20.  
    21. public class EntityClone : MonoBehaviour {
    22.  
    23.     [SerializeField]
    24.     public Mesh mesh;
    25.  
    26.     [SerializeField]
    27.     public UnityEngine.Material material;
    28.  
    29.     private EntityManager em;
    30.  
    31.     public int NumToCreate;
    32.  
    33.     public float Spacing;
    34.  
    35.     public void Start () {
    36.  
    37.         em = World.DefaultGameObjectInjectionWorld.EntityManager;
    38.  
    39.         EntityArchetype ea = em.CreateArchetype (
    40.             typeof (Translation),
    41.             typeof (LocalToWorld),
    42.             typeof (RenderMesh),
    43.             typeof (PhysicsCollider),
    44.             typeof (PhysicsVelocity),
    45.             typeof (AtomicSpeciesData)
    46.         );
    47.         NativeArray<Entity> entityArray = new NativeArray<Entity> (NumToCreate, Allocator.Temp);
    48.         em.CreateEntity (ea, entityArray);
    49.         for (int i = 0; i < entityArray.Length; i++) {
    50.             Entity entity = entityArray[i];
    51.             em.SetSharedComponentData (entity, new RenderMesh {
    52.                 mesh = mesh,
    53.                 material = material
    54.             });
    55.             em.SetComponentData (entity, new Translation { Value = new Unity.Mathematics.float3 (Spacing * i, Spacing * i, Spacing * i) });
    56.             em.SetComponentData (entity, new PhysicsVelocity { Angular = new Unity.Mathematics.float3 (0, 5, 0),
    57.                 Linear = new Unity.Mathematics.float3(0,0,10) });
    58.             em.SetComponentData (entity, new AtomicSpeciesData { atomicSpecies = AtomicSpeciesData.AtomicParticleSpecies.Electron  });
    59.         }
    60.  
    61.         //Clean up the array as we do not need to keep it in memory anymore.
    62.         entityArray.Dispose ();
    63.     }
    64. }
    65.  
    Gonna try indexing into the PhysicsCollider Value and see what that brings..then creating them over time and finally adding the physics sim to the world..however that is done. I placed a PhyicsStep component on an Empty GameObject but it wanted to be an entity to run..so I did and it didn't create the other 500 entities I am testing with.. So That puzzle will have to wait. Go figure is the name of this game.
     
  22. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    Im not sure about what you are attempting to achieve, But I created this scene.

    It creates 200 Entities of "Atoms" of differing colors and I add a ProtonTag component to them all and then retrieve them all in the System.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.Entities;
    5. using Unity.Transforms;
    6. using Unity.Mathematics;
    7. using Unity.Collections;
    8.  
    9. public class CloneBalls : ComponentSystem
    10. {
    11.  
    12.     public Entity entity;
    13.  
    14.     private float spawnTimer;
    15.  
    16.     public int currentNumEntitys;
    17.     public int maxEntitys = 200;
    18.  
    19.     NativeArray<Entity> Atoms;
    20.  
    21.  
    22.     protected override void OnUpdate()
    23.     {
    24.         spawnTimer -= Time.DeltaTime;
    25.  
    26.         EntityQuery myQuery = GetEntityQuery(typeof(ProtonTag));
    27.  
    28.         Atoms = myQuery.ToEntityArray(Allocator.Persistent);
    29.  
    30.         currentNumEntitys = Atoms.Length;
    31.  
    32.         if((spawnTimer <= 0f) && (currentNumEntitys < maxEntitys))
    33.         {
    34.             spawnTimer = .5f;
    35.  
    36.             Entities.ForEach((ref ProtonTag ptag) =>
    37.             {
    38.  
    39.             Entity e = EntityManager.Instantiate(ptag.Atom);
    40.          
    41.                 EntityManager.SetComponentData(e, new Translation { Value = new float3(
    42.                     UnityEngine.Random.Range(-90,90),
    43.                     10f,
    44.                     UnityEngine.Random.Range(-90f,90f)
    45.                     )
    46.                 });
    47.  
    48.             });
    49.  
    50.  
    51.                 Debug.Log(currentNumEntitys);
    52.  
    53.          
    54.  
    55.  
    56.  
    57.         }
    58.  
    59.  
    60.  
    61.         Atoms.Dispose();
    62.  
    63.  
    64.      
    65.  
    66.     }
    67. }
    68.  
    There is a small issue atm with the "System" and it actually reports 192 Entities but shows 384 Entities in the EntityDebugger So i,ll look at that after dinner. :D

    The plane is 10x0x10.

    If this is something you are looking to get I can upload the package so you can take a look.
     

    Attached Files:

    Last edited: Feb 1, 2020
  23. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,015
    I have 5K electrons bouncing and my lifetime component works dandy. I think after I Destroy the entities exceeding their lifetime I get a Null Reference error that seems I did not clean up some native container or array. If I use an EntityCommandBuffer.Concurrent I am not sure what to Dispose() after the job is finish. I saw Unity's example returned default. I tried that and got an error every frame.
     
  24. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    Hi,

    Can you post your code for the 5k bouncing orbs please, So i can see how you done it, I seem to get some FPS drops when I get close to a 1000 for some reasong would just to compare :)
     
  25. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,015
    Sure..here it is..thrills me to no end to see that many at bouncing at 120fps
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.Entities;
    5. using Unity.Collections;
    6. using Unity.Rendering;
    7. using Unity.Transforms;
    8. using Unity.Physics;
    9. using Unity.Mathematics;
    10. using Collider = Unity.Physics.Collider;
    11. using Unity.Burst;
    12. [BurstCompile]
    13.  
    14. public class EntityClone : MonoBehaviour {
    15.  
    16.     [SerializeField]
    17.     public Mesh mesh;
    18.  
    19.     [SerializeField]
    20.     public UnityEngine.Material material;
    21.  
    22.     [SerializeField]
    23.     public Transform firingPositionObject;
    24.     public Vector3 initialPosition;
    25.     public Quaternion initialRotation;
    26.     public Vector3 initialImpulseDirection;
    27.     public float initialImpulseForce;
    28.     public float friction = 0.25f;
    29.     public float restitution = 0.5f;
    30.  
    31.     public Vector3 angularMomentum;
    32.     public float mass;
    33.     public float gravityFactor;
    34.  
    35.     private EntityManager em;
    36.     private PhysicsWorld physWorld;
    37.     public int NumToCreate;
    38.  
    39.     public float Spacing = 0.1;
    40.  
    41.     public void Start () {
    42.         if (mass == 0f) { mass = 1f; }
    43.         initialPosition = firingPositionObject.position;
    44.         initialRotation = firingPositionObject.rotation;
    45.         initialImpulseDirection = firingPositionObject.TransformVector (firingPositionObject.forward) * initialImpulseForce;
    46.         em = World.DefaultGameObjectInjectionWorld.EntityManager;
    47.         EntityArchetype ea = em.CreateArchetype (
    48.             typeof (Transform),
    49.             typeof (Translation),
    50.             typeof (LocalToWorld),
    51.             typeof (Rotation),
    52.             typeof (RenderMesh),
    53.             typeof (PhysicsVelocity),
    54.             typeof (PhysicsCollider),
    55.             typeof (PhysicsGravityFactor),
    56.             typeof (PhysicsDamping),
    57.             typeof (PhysicsMass),
    58.         );
    59.         NativeArray<Entity> entityArray = new NativeArray<Entity> (NumToCreate, Allocator.Temp);
    60.         em.CreateEntity (ea, entityArray);
    61.         for (int i = 0; i < entityArray.Length; i++) {
    62.  
    63.             Entity entity = entityArray[i];
    64.  
    65.             em.SetSharedComponentData (entity, new RenderMesh {
    66.                 mesh = mesh,
    67.                 material = material
    68.             });
    69.             em.SetComponentData (entity, new Translation { Value = new float3 (Spacing * i, Spacing * i, Spacing * i) });
    70.             em.SetComponentData (entity, new Rotation { Value = new float4 (0f, 0f, 0f, 1f) });
    71.  
    72.  
    73.             em.SetComponentData (entity, new PhysicsVelocity {
    74.                 Angular = new float3 (angularMomentum.x, angularMomentum.y, angularMomentum.z),
    75.                 Linear = new float3 (initialImpulseDirection.x, initialImpulseDirection.y, initialImpulseDirection.z)
    76.             });
    77.  
    78.             em.SetComponentData (entity, new PhysicsGravityFactor { Value = gravityFactor });
    79.  
    80.  
    81.             em.SetComponentData (entity, new PhysicsMass {
    82.                 Transform = RigidTransform.identity,
    83.                 CenterOfMass = new float3 (0f, 0f, 0f),
    84.                 InverseMass = mass
    85.             });
    86.  
    87.             /*
    88.             em.SetComponentData (entity, PhysicsMass.CreateDynamic (new MassProperties (), mass));
    89.             */
    90.             var physMaterial = new Unity.Physics.Material {
    91.                 CustomTags = Unity.Physics.Material.Default.CustomTags,
    92.                 Flags = Unity.Physics.Material.MaterialFlags.EnableCollisionEvents |
    93.                     Unity.Physics.Material.MaterialFlags.EnableMassFactors |
    94.                     Unity.Physics.Material.MaterialFlags.EnableSurfaceVelocity,
    95.                 Friction = friction,
    96.                 FrictionCombinePolicy = Unity.Physics.Material.Default.FrictionCombinePolicy,
    97.                 Restitution = restitution,
    98.                 RestitutionCombinePolicy = Unity.Physics.Material.Default.RestitutionCombinePolicy,
    99.             };
    100.  
    101.  
    102.             em.SetComponentData (entity, new PhysicsCollider {
    103.                 Value = Unity.Physics.SphereCollider.Create (new SphereGeometry () {
    104.                     Center = new float3 (0f, 0f, 0f),
    105.                     Radius = 0.25f,
    106.                 },CollisionFilter.Default, physMaterial)
    107.             });
    108.            
    109.         }
    110.  
    111.         //Clean up the array as we do not need to keep it in memory anymore.
    112.         entityArray.Dispose ();
    113.     }
    I have extended your initial script into several types of emitters now.. In this I still use spacing as I was testing adding everything here and then transferred and altered code to fire from the firingpositionObj and use its Z axis as the initialImpulseDirection. I would have included it here but this is better for checking counts to have them all burst at the start. I set the spacing to less than the radius of the objects so they would "explode" away from each other.
    Next up is the critical collision code. Bit confused still about patterns.. Like where to set a gameobject to be read for position and such in the non-hybrid ECS.. I get building rube goldberg widgets from scratch using archetypes.
     
  26. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    Wow looks intricate!, I am still new to programming in C# so some of the things(well quite a few give me issues tbh)

    I notice that you create all the components inside the script sucj as Transform, Translation, LocalToWorld, Rotation and a lot of the Physics Components.

    Just as a test you might be able to put them all on in the editor and then use a ConvertToEntity component which will do all the heavy lifting for you, I will try it out for you and get back to you on that, Unless maybe because I use a ConvertToEntity Component is why my entities start to FPS dp at about 1000, Interesting trial and error. ;)

    I tried adding force to a physics body but wasnt too sure how to do it, I knew I had to start with

    Entities.ForEach((Entity e, ref AtomTag atag, ref PhysicsVelocity pVelocity) => {

    });

    Randomly even when using
    using Unity.Physics
    using Havok.Physics

    I cannot seem to find a component in the ref PhysicsBody pBody (There seems to be no definition for it even though when I converttoentity the entity has a PhysicsBody component.

    Once other thing I am struggling with is that with the code above how do I know how many entities are "affected" by the Entities.ForEach ??

    Sorry if these are simple questions but just wondered if you had any ideas :)

    Thanks for posting your code !
     
  27. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,015
    In my short experience the ConvertToEntity script causes me more issues with doubled meshes and then not knowing how to access the monobehaviour scripts on them.. So fine for some games, but this systems physics is sorely needed for a game based on subatomic simulations inside tokamaks, particle accelerators, rube goldberg machines. I stripped it back for the cut and paste to this thread. I think the PhysicsBody is a composite of PhysicsVelocity, PhysicsMass, PhysicsMaterial and PhysicsCollider. I did not get any action at all until I added the InverseMass = mass. I also have added the AtomicSpeciesData and LifetimeData components I created to the Archetype.

    Prior I had a whole PhysicsTransaction system I had to turn off due to not being able to have at most 100 rigidbodies in a scene before framerate started dropping so querying interactions for repulsion, attraction, paramagnetics and magnetics was not possible. Now it is. In this script you can set the initialImpulse and multiply it by the initialImpulseDirection. I get that direction from a firingPositionObj which is just an empty gameObject at the position I am emitting from and the z axis pointing in the direction I want to fire. You really don't need to set velocity after firing an emitter.

    I think I saw in Physics.Extensions a few methods for applying an Impulse Force like in standard Unity PhysX. When converting the probe vehicle I will be altering velocity frame by frame and using a PID controller to stabilize the rigidbody vehicle physics. A PID controller makes proportional, integral and derivative calculations based on the input to drive the rigidbody and resolves the controller input to stabilize the system oscillations and is used in all kinds of industrial systems.
     
  28. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    nicolasgramlich likes this.
  29. Shabbalaka

    Shabbalaka

    Joined:
    Jan 15, 2018
    Posts:
    152
    After examining this Blog I noticed that the MovementCode for the Entity with the NavMesh is still running in the main thread

    Code (CSharp):
    1.  
    2. public class EnemySystem : ComponentSystem
    3. {
    4.     private EntityQuery query;
    5.     private const float kDistanceFromPlayer = 2f;
    6.  
    7.     protected override void OnCreate()
    8.     {
    9.         query =
    10.             GetEntityQuery(
    11.                 ComponentType.ReadOnly<EnemyData>());
    12.     }
    13.  
    14.     protected override void OnUpdate()
    15.     {
    16.         Entities.With(query).ForEach((Entity e, EnemyData enemy) =>
    17.         {
    18.             switch(enemy.EnemyState)
    19.             {
    20.                 case EnemyState.Chase:
    21.                     {
    22.                         UpdateChaseState(enemy);
    23.                         break;
    24.                     }
    25.                 case EnemyState.Attack:
    26.                     {
    27.                         UpdateAttackState(enemy);
    28.                         break;
    29.                     }
    30.             }
    31.         });
    32.     }
    33.  
    34.     private void UpdateChaseState(EnemyData enemyData)
    35.     {
    36.         enemyData.NavMeshAgent.isStopped = false;
    37.         enemyData.NavMeshAgent.speed = enemyData.Speed;
    38.         enemyData.NavMeshAgent.SetDestination(GameManager.Instance.PlayerPosition);
    39.         if (Vector3.Distance(GameManager.Instance.PlayerPosition, enemyData.Position) < kDistanceFromPlayer)
    40.         {
    41.             enemyData.SetState(EnemyState.Attack);
    42.         }
    43.     }
    44.  
    45.     private void UpdateAttackState(EnemyData enemyData)
    46.     {
    47.         Debug.Log("I ATTACK YOU!!!!!");
    48.         enemyData.NavMeshAgent.isStopped = true;
    49.  
    50.         if (Vector3.Distance(GameManager.Instance.PlayerPosition, enemyData.Position) > kDistanceFromPlayer)
    51.         {
    52.             enemyData.SetState(EnemyState.Chase);
    53.         }
    54.     }
    55. }

    Which is essentially the same as what I done in
    EnemyMovementSystem.cs
    [ECS System using a Injected GameObject on ConvertToEntity]

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.Entities;
    5. using UnityEngine.AI;
    6. using Unity.Transforms;
    7. using Unity.Mathematics;
    8.  
    9. public class EnemyMovementSystem : ComponentSystem
    10. {
    11.     protected override void OnUpdate()
    12.     {
    13.         var playerEntity = GetSingletonEntity<PlayerTagID>();
    14.         var playerTranslation = EntityManager.GetComponentData<Translation>(playerEntity);
    15.         Vector3 convertPos = new Vector3(playerTranslation.Value.x,playerTranslation.Value.y,playerTranslation.Value.z);
    16.         //Debug.Log(convertPos);
    17.         //To Access NavMeshAgents using ConvertToEntity we must Inject the game object NavMeshAgents are NOT converted to Entity Components!!
    18.         Entities.WithAll<EnemyMovementControllerData>().ForEach((ref Translation ImagePosition, NavMeshAgent nma) =>
    19.         {
    20.                 nma.SetDestination(convertPos);
    21.         });
    22.     }
    23. }
    24.  
    25.  
    EnemySpawnAndChasePlayer.cs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.AI;
    5.  
    6. public class EnemySpawnAndChasePlayer : MonoBehaviour
    7. {
    8.     public int numbertospawn;
    9.     public GameObject Player;
    10.     public GameObject prefab;
    11.     public Transform startSpawnSpot;
    12.     public NavMeshAgent nma;
    13.     public List<NavMeshAgent> Agents = new List<NavMeshAgent>();
    14.  
    15.     private void Awake() {
    16.        
    17.         for(int i = 0; i<numbertospawn; i++)
    18.         {
    19.             GameObject newObj = Instantiate(prefab, new Vector3(startSpawnSpot.position.x - i, startSpawnSpot.position.y, startSpawnSpot.position.z), Quaternion.identity);
    20.            
    21.             nma = newObj.GetComponent<NavMeshAgent>();
    22.            // nma.SetDestination(Player.transform.position);
    23.             nma.SetDestination(Player.transform.position);
    24.             Agents.Add(nma);
    25.         }
    26.     }
    27.     // Update is called once per frame
    28.     void Update()
    29.     {
    30.  
    31.         foreach(NavMeshAgent agent in Agents)
    32.         {
    33.             agent.SetDestination(Player.transform.position);
    34.         }
    35.     }
    36. }
    37.  
    Now my question being is running in a ComponentSystem faster than in a Monobehaviour, I am just asking due to if OnUpdate runs on the main thread and ComponentSystem OnUpdate runs on a main thread whats the difference?
     
unityunity