#Decreacing operations needed for gravity

1 messages · Page 1 of 1 (latest)

boreal oracle
#
void N2Loop()
    {
        
        for(int myPlanetIndex = 0; myPlanetIndex < massObjects.Count; myPlanetIndex++)
        {
            
            Vector3 myPosition = massObjects[myPlanetIndex].position;
            float myMass= massObjects[myPlanetIndex].mass;
            CelestialBody myPlanet = massObjects[myPlanetIndex];
            for (int otherPlanetIndex = 0; otherPlanetIndex < massObjects.Count; otherPlanetIndex++)
            {
                if (otherPlanetIndex == myPlanetIndex) continue;
                Vector3 distance3 = massObjects[otherPlanetIndex].position - myPosition;
                float distance= Mathf.Clamp((distance3).magnitude, massObjects[otherPlanetIndex].radius+ massObjects[myPlanetIndex].radius,10000);
                float force = (myMass * massObjects[otherPlanetIndex].mass) / (distance * distance);
                myPlanet.velocity += (distance3.normalized * force)/myMass/100;
               

            }
         
            myPlanet.position += myPlanet.velocity;
            massObjects[myPlanetIndex]=myPlanet;
            massObjects[myPlanetIndex].UpdateGameObject();
        }
    }

This is some code I wrote, it itterates trough each element of a list for each element, does someone have advice on how I could reduce the number of operations so that it s not n^2 anymore?

raw aspen
boreal oracle
raw aspen
#

You have a lot of physics going on here.

#

I suggest that each planet would have their own "Velocity" to manage, and if another planet comes into "effect", you'd append the result to a queue, and then apply the value at the end of LateUpdate()

#

This will get away from using array collections of planet, and rely on object oriented approach.

#

Use Queue<T> system to gather "Affecting" velocity from other planet during an update() call, and then apply the value in LateUpdate().

#

Doing this will effectively eliminate the second for loop.

#

Also, consider using Unity's physics (e.g. OnTriggerEnter/OnTriggerExit) to take consideration about planets that are affected by the current celestial body.

boreal oracle
#

So do you mean that each planet has a list of planets to use for it s in range gravitation, or that I split up my world into a grid and then for further away planets I just take the average value of each planet?

raw aspen
#

Each planet is responsible to check and apply forces when needed. The script above treats like you have a single manager responsible to manage the planet's behaviour.

#

Define the behavior from the planet's perspective, instead of manager perspective.

boreal oracle
#

okay yes I get that now, this seems great but how does the individual planet get access to the other planets, positions and masses?

raw aspen
#

You already have their reference when they enter the trigger.

boreal oracle
#

yes, but doesn t each planet having it s own trigger make a huge impact on performance, like doesn t that mean that each trigger has to check for each other trigger if it s in it s range again?

raw aspen
#

OnTriggerEnter is called once it enters, not every frame.

#

When it exit, it calles OnTriggerExit.

#

Each planet would have their own collection of the affected planets in their magnetosphere.

#

So instead of having two for-each loop

#

you simpify it down to one for-each loop because you're going through a single collection

boreal oracle
#

I will have one for loop and one foreach in range, but I can t understand how the triggers in unity work, like there s somewhere still gotta be a if (distance<triggerrange) in the unity code

raw aspen
#

you don't need foreach in range

#

OnTriggerEnter/Exit handles this for you

boreal oracle
#

yes but how does OnTrigger do this, because as far as I understand this would mean that for each frame the Trigger will have to check for all other triggers if they are in range, or am I wrong?

#

-close

#

!close

raw aspen
#

Wrong, Physics will notify any script that have OnTriggerEnter/Exit implementation.

#

So it's not checking every frame.

#

This is done already through Physics engine.

raw aspen