#Decreacing operations needed for gravity
1 messages · Page 1 of 1 (latest)
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?
#854851968446365696 on code formatting.
does this mean u will help me now?
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.
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?
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.
okay yes I get that now, this seems great but how does the individual planet get access to the other planets, positions and masses?
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?
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
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
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
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.
Wrong, OnTriggerEnter fired once when object with rigidbody comes into range. You would then store this inside your planet's collection to check.