- Home /
Independently using the same script on multiple game objects?
I feel like this question should already be answered but I've scoured the internet and I can't figure out anything that helps.
I've making a space game and I've written a script which draws the ellipse of the orbit of an object, based on its own velocity and position. If I apply this script to one object, it works great! But if I have it on two objects at the same time, the orbits get all messed up. It seems like all the variables are being shared between the same script for different game objects? I saw somewhere on the forums to make all my variables public, but that didn't help either... Any help would be greatly appreciated!!
Here's the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OrbitDrawer : MonoBehaviour
{
public GameObject thing;
public Rigidbody2D rb;
public GameObject attractor;
public Vector3 targetDir;
public float direction;
public float force;
public float gravConst = 0.004F;
public float distance;
public float sgp;
public static Vector3 angMom;
public float angMomMag;
public float redMass;
public Vector3 specRelAngMom;
public float specRelAngMomMag;
public Vector3 newSpecRelAngMom;
public static float orbEnergy;
public static float sma;
public static float eccent;
public float alpha;
public static float periapsis;
public static float apoapsis;
public Vector2 ecVec;
public Vector3 angVel;
public float angVelMag;
public float momOfInertia;
public float flightPathAngle;
public static float sMina;
public float centerHeight;
public Vector3 Center;
public static Vector3 Forceforce;
public Vector3 actualAttractorToPlayer = Vector3.zero;
public Vector3 previousAttractorToPlayer = Vector3.zero;
public float angleDifference;
public float orbitalAngle;
public float a = 2;
public float b = 1;
public float h = 0;
public float k = 0;
public float theta = 0;
public int resolution = 1000;
public Vector3[] positions;
public float orbitWidth;
public static float height;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
a = sma;
b = sMina;
theta = orbitalAngle;
centerHeight = apoapsis - sma;
h = centerHeight * Mathf.Cos(theta * Mathf.Deg2Rad);
k = centerHeight * Mathf.Sin(theta * Mathf.Deg2Rad);
positions = CreateEllipse(a, b, h, k, theta, resolution);
LineRenderer lr = GetComponent<LineRenderer>();
lr.positionCount = resolution + 1;
for (int i = 0; i <= resolution; i++)
{
lr.SetPosition(i, positions[i]);
}
lr.startWidth = Camera.main.orthographicSize * orbitWidth;
lr.endWidth = Camera.main.orthographicSize * orbitWidth;
}
void FixedUpdate()
{
//All the maths!!
targetDir = attractor.transform.position - thing.transform.position;
distance = Vector2.Distance(thing.transform.position, attractor.transform.position);
force = ((Planet.mass * rb.mass * gravConst) / (distance * distance));
Vector2 dir = targetDir.normalized;
rb.AddForce(dir * force, ForceMode2D.Force);
sgp = gravConst * (Planet.mass + rb.mass);
//Calculate Specific Relative Angular Momentum(Cross of the position and the velocity vectors)
specRelAngMom = Vector3.Cross(thing.transform.position, rb.velocity);
specRelAngMomMag = specRelAngMom.magnitude;
//Calculate orbital energy
orbEnergy = ((rb.velocity.magnitude * rb.velocity.magnitude) / 2) - (sgp / distance);
//Calculate semi-major axis and semi-minor axis
sma = -(sgp / (2 * orbEnergy));
sMina = sma * (Mathf.Sqrt(1 - (eccent * eccent)));
//Calculate Eccentricity Vector(vector from the apopapsis to the periapsis)
ecVec = ((Vector3.Cross(rb.velocity, specRelAngMom)) / sgp) - (thing.transform.position / thing.transform.position.magnitude);
//Make the orbital angle negative when it should be
if (Vector3.Cross(new Vector3(1, 0, 1), (ecVec * -1)).x < 0)
{
orbitalAngle = Vector3.Angle(new Vector3(1, 0, 0), (ecVec * -1));
}
else
{
orbitalAngle = -Vector3.Angle(new Vector3(1, 0, 0), (ecVec * -1));
}
//Calculate Eccentricity
eccent = Mathf.Sqrt(1 + ((2 * (orbEnergy) * specRelAngMomMag * specRelAngMomMag) / (sgp * sgp)));
//Calculate periapsis and apoapsis
periapsis = ((1 - eccent) * sma);
apoapsis = ((1 + eccent) * sma);
}
//Function for creating an ellipse. a is sma, b is sMina, (k, h) is the center, theta is the angle, and resolution is the number of points on the ellipse
Vector3[] CreateEllipse(float a, float b, float h, float k, float theta, int resolution)
{
positions = new Vector3[resolution + 1];
Quaternion q = Quaternion.AngleAxis(theta, Vector3.forward);
Vector3 center = new Vector3(h, k, -0.0f);
for (int i = 0; i <= resolution; i++)
{
float angle = (float)i / (float)resolution * 2.0f * Mathf.PI;
positions[i] = new Vector3(a * Mathf.Cos(angle), b * Mathf.Sin(angle), -0.0f);
positions[i] = q * positions[i] + center;
}
return positions;
}
}
You are using many static variables and that's what's causing the problem.
Static variable values are shared between all instances of the object.
So, just remove the static keyword from all variable declarations, whose values you want to be unique for each instance.
Thank you!! I knew there was something I just wasn't getting.
You are welcome!
Please don't forget to mark my reply as the accepted answer (Click the check-mark icon to make it green)
Answer by Lilius · Feb 25, 2018 at 02:06 PM
Make your variables private instead. And don't use static variables, they most likely cause things to get messed up when using same script on many objects.
I have a very similar problem, but I need to access the variables in my script from another script - so I'm assu$$anonymous$$g I need to have public variables.
Should I be making function calls ins$$anonymous$$d?
You should not use static variables just to have an easy access to variable. Getting reference to object and accessing its public (non static) variables is better, but using properties is even better: https://docs.microsoft.com/en-us/dotnet/csharp/program$$anonymous$$g-guide/classes-and-structs/properties
Answer by DrawMen1999 · Sep 12, 2019 at 04:49 PM
Static variables are shared by every instance of the script, so remove the static and it should work.