Search Unity

Trying to do a solar system

Discussion in 'Entity Component System' started by Vectrex, May 30, 2020.

  1. Vectrex

    Vectrex

    Joined:
    Oct 31, 2009
    Posts:
    267
    Hey, I'm trying to convert my very simple (and inefficient) gravity setup to ECS. How would I iterate through every gravity entity INSIDE the system Entities.ForEach thing? I'm really confused!
     
  2. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
  3. Vectrex

    Vectrex

    Joined:
    Oct 31, 2009
    Posts:
    267
    Here's my quick test in Mono. It's really crappy, but it's just a test and it works ok. Each gravity entity adds itself to the gravityTransform list.

    Each body loops through every other body and applies forces to it. The 2nd example is where I moved this to a more efficient gravityManager that better loops through bodies, which I imagine would work better for ECS type setup

    Code (CSharp):
    1.     public void Update()
    2.     {
    3.         for( int i = 0; i<gravityBodies.Count; i++ )
    4.         {
    5.             direction = myTransform.position - gravityTransforms[i].position;
    6.             //distance = direction.sqrMagnitude;
    7.             distance = direction.magnitude;
    8.  
    9.             if( distance>10 ) // && distance < 1000)
    10.             {
    11.                 //direction = direction/distance; // More efficient normalise (no sqrR)
    12.                 direction.Normalize();
    13.  
    14.                 force = forceScalar * (direction * (body.mass * gravityBodies[i].mass) / (distance * (distance / 2)));
    15.                 gravityBodies[i].AddForce(force * Time.deltaTime);
    16.                 // totalGravityBodies[i].AddForce( force );
    17.             }
    18.         }
    19.     }
    20.  
    Code (CSharp):
    1.     public void Update()
    2.     {
    3.         deltaTime = Time.deltaTime;
    4.      
    5.         for (int currentBody = 0; currentBody < bodies.Count; currentBody++)
    6.         {
    7.             for (int bodyToAffect = 0; bodyToAffect < bodies.Count; bodyToAffect++)
    8.             {
    9.                 direction = bodies[currentBody].position - bodies[bodyToAffect].position;
    10.                 distance  = direction.magnitude;
    11.  
    12.                 if (distance > 10) // && distance < 1000)
    13.                 {
    14.                     //direction = direction/distance; // More efficient normalise (no sqrR)
    15.                     direction.Normalize();
    16.  
    17.                     force = gravityComponents[currentBody].forceScalar *
    18.                             (direction * (bodies[currentBody].mass * bodies[bodyToAffect].mass) /
    19.                              (distance * (distance / 2)));
    20.                     bodies[bodyToAffect].AddForce(force * deltaTime);
    21.                     // forces[currentBody] += force;
    22.                 }
    23.             }
    24.         }
    25.  
    26.         // for (int i = 0; i < bodies.Count; i++)
    27.         // {
    28.             // bodies[i].AddForce(forces[i]); // * deltaTime);
    29.         // }
    30.     }
    31.  
     
  4. Vectrex

    Vectrex

    Joined:
    Oct 31, 2009
    Posts:
    267
    Here's my attempt in DOTS. The inner foreach seems to work, but the impulse just isn't applied (even with a hack massive number).
    The entity from the Entities.ForEach can be moved with the same "ComponentExtensions.ApplyLinearImpulse" line though (outside the inner normal foreach)

    Code (CSharp):
    1.     protected override void OnUpdate()
    2.     {
    3.         deltaTime = Time.DeltaTime;
    4.  
    5.         NativeArray<Entity> allEntities = EntityManager.GetAllEntities(Allocator.Temp);
    6.  
    7.         Entities.ForEach((Entity                currentEntity,
    8.                           ref Translation       currentTranslation,
    9.                           ref Gravity_DOTS_Data currentGravityData,
    10.                           ref PhysicsMass       physicsMassCurrent,
    11.                           ref PhysicsVelocity   physicsVelocity
    12.                          ) =>
    13.                          {
    14.                              foreach (Entity affectedEntity in allEntities)
    15.                              {
    16.                                  if (EntityManager.HasComponent<Gravity_DOTS_Data>(affectedEntity))
    17.                                  {
    18.                                      Translation affectedTranslation =
    19.                                          EntityManager.GetComponentData<Translation>(affectedEntity);
    20.                                      PhysicsMass physicsMassAffected =
    21.                                          EntityManager.GetComponentData<Unity.Physics.PhysicsMass>(affectedEntity);
    22.                                      PhysicsVelocity physicsVelocityAffected =
    23.                                          EntityManager.GetComponentData<Unity.Physics.PhysicsVelocity>(affectedEntity);
    24.  
    25.                                      direction = currentTranslation.Value - affectedTranslation.Value;
    26.  
    27.                                      // distance  = direction.magnitude;
    28.                                      distance = math.distance(currentTranslation.Value,
    29.                                                               affectedTranslation.Value);
    30.  
    31.  
    32.                                      // if (distance > 10) // && distance < 1000)
    33.                                      // {
    34.                                      direction = math.normalize(direction);
    35.  
    36.                                      force = currentGravityData.forceScalar *
    37.                                              (direction * (physicsMassCurrent.InverseMass *
    38.                                                            physicsMassAffected.InverseMass) /
    39.                                               (distance * (distance / 2)));
    40.  
    41.                                      ComponentExtensions.ApplyLinearImpulse(ref physicsVelocityAffected,
    42.                                                                             physicsMassAffected,
    43.                                                                             force * 1000f);
    44.                                      // }
    45.                                  }
    46.                              }
    47.                          }
    48.                         );
    49.     }