- Home /
Need help on my script to calculate gravity for a mass
Hello,
I'm trying to make a 2D simulation game of planets with gravity that will let you place planets. I've made a script that will add gravity to every object in the scene but it requires the main sun to orbit, Basically i'm trying to make a script that will add gravity to every object based on its mass and not have to have on object be the main orbit so everything can move and big objects will influence most over little objects. My script right now is okay but its not what i'm trying to get and I just have no idea what to do now. using UnityEngine;
public class PlanetGravity : MonoBehaviour {
public float massmul;
public GameObject sun;
void FixedUpdate () {
foreach (GameObject o in UnityEngine.Object.FindObjectsOfType<GameObject>())
{
Rigidbody2D RBody = o.GetComponent<Rigidbody2D>();
if (RBody && o != sun)
{
RBody.AddForce((sun.transform.position - o.transform.position).normalized * (RBody.mass * massmul) / Vector3.Distance(sun.transform.position, o.transform.position));
}
}
}
}
If anyone could help ill appreciate it!
Answer by TheSOULDev · Sep 13, 2017 at 01:21 AM
You should use the newtonian formula for force if you intend to emulate gravity:
https://en.wikipedia.org/wiki/Newton%27s_law_of_universal_gravitation
Your current formula is something like direction * mass / r, which barely has to do anything with gravity.
I did what you said and came out with this
RBody.AddForce((sun.transform.position - o.transform.position).normalized*Strength * (RBody.mass / sun.GetComponent<Rigidbody2D>().mass)/Vector2.Distance(RBody.transform.position, sun.transform.position));
From running it it looks like its working and its how I like but I still want to know how to make it affect everything ins$$anonymous$$d of it requiring a sun game object as the main point of orbit.
You should do it like this:
First you should introduce the gravitational constant in the script you keep static constants in. I call $$anonymous$$e Constants, so it would looks like this:
public static class Constants
{
//Some constants...
public static double G = 0x3DD25854F5E5FB25;
//Some other constants...
}
Then you should create a Sun class which will act like your imaginary sun and have functions in it:
public class Sun
{
Vector3 Center;
double $$anonymous$$ass;
public Sun(Vector3 CenterOfSun, double $$anonymous$$assOfSun)
{
Center = CenterOfSun;
$$anonymous$$ass = $$anonymous$$assOfSun;
}
public void $$anonymous$$ove(Vector3 NewPosition)
{
Center = NewPosition;
}
public void Assign$$anonymous$$ass(double New$$anonymous$$ass)
{
$$anonymous$$ass = (New$$anonymous$$ass > 0) ? New$$anonymous$$ass : 0;
}
public void Change$$anonymous$$ass(double Offset)
{
if(Offset > 0)
$$anonymous$$ass = (Offset > double.$$anonymous$$axValue - $$anonymous$$ass) ? double.$$anonymous$$axValue : ($$anonymous$$ass + Offset);
else
$$anonymous$$ass = (-Offset > $$anonymous$$ass) ? 0 : ($$anonymous$$ass + Offset);
}
public void GravityPull(Rigidbody PulledObject)
{
Vector3 ResultingVector = (Center - PulledObject.centerOf$$anonymous$$ass);
Vector3 ForceToAdd = ResultingVector.normalized * (float)((Constants.G * PulledObject.mass * $$anonymous$$ass) / ResultingVector.sqr$$anonymous$$agnitude);
PulledObject.AddForce(ForceToAdd);
}
public void GravityPull(Rigidbody2D PulledObject)
{
Vector3 ResultingVector = (Center - PulledObject.centerOf$$anonymous$$ass);
Vector3 ForceToAdd = ResultingVector.normalized * (float)((Constants.G * PulledObject.mass * $$anonymous$$ass) / ResultingVector.sqr$$anonymous$$agnitude);
PulledObject.AddForce(ForceToAdd);
}
}
All that is left to do is to run a foreach loop with rigidbodies in a system when you want to add force, and you don't need to do this every frame, but maybe every 0.1s. The difference won't really be noticeable unless there is a lot of drag.
EDIT: As for the use, just do this:
//First instantiate a Sun in some script, preferably in Start(). Would be cool if you had some sort of preset variables from the inspector, so do something like this:
public Vector3[] SunCenter;
public double[] Sun$$anonymous$$ass;
public int SunAmount;
void Start()
{
List<Sun> SunList = new List<Sun>();
for(int i = 0; i < SunAmount; i++)
SunList.Add(new Sun(SunCenter[i], Sun$$anonymous$$ass[i]));
}
Could you explain how I need to set this up? I never even used a class and don't know anything about classes. Could you also explain to me classes or link me to a page I could read about them? I'm a beginner at scripting I guess from $$anonymous$$e compared to yours so if you could help me i'll appreciate it.