Hi,
A. Problem:
I’m writing a n-body gravity simulation and I’m currently getting the following NullReferenceException errors while trying to get a reference to an instantiated gameobject via GetComponent.
-
NullReferenceException: Object reference not set to an instance of an object Init.Awake () (at Assets/Scripts/Init.cs:12)
-
NullReferenceException: Object reference not set to an instance of an object GravityManager.FixedUpdate () (at Assets/Scripts/GravityManager.cs:53)
Any help would be greatly appreciated!
B. Expected behavior
Init.cs should:
- Instantiate a GravityManager instance
- Instantiate Sphere “sphere1” (line 12), which should be added to the gravity manager’s Sphere list “bodies”. <This is where the NullReferenceException is occurring>
The gravity manager instance should update the positions of each sphere in “bodies” each frame via FixedUpdate(). Currently, the manager only implements SHM about the origin using a 4th order symplectic integrator (Symplectic integrator - Wikipedia).
C. Code
(also at: orbits/Assets/Scripts at gm · Justin08784/orbits · GitHub)
Init.cs:
using UnityEngine;
public class Init : MonoBehaviour
{
public GameObject Sphere_Prefab;
public GameObject Gravity_Manager_Prefab;
void Awake()
{
Instantiate(Gravity_Manager_Prefab, Vector3.zero, Quaternion.identity);
GameObject sphereObject1 = Instantiate(Sphere_Prefab, new Vector3(2, 0, 0), Quaternion.identity);
Sphere sphere1 = sphereObject1.GetComponent<Sphere>();
// Sphere sphere2 = Instantiate(Sphere_Prefab, new Vector3(-2, 0, 0), Quaternion.identity).GetComponent<Sphere>();
GravityManager.register_body(sphere1);
// GravityManager.register_body(sphere2);
}
}
GravityManager.cs:
using System;
using System.Collections.Generic;
using UnityEngine;
public class GravityManager : MonoBehaviour
{
private static GravityManager Instance; // there should be only 1 manager
private static List<Sphere> bodies;
private readonly double c = Math.Pow(2.0, 1.0/3.0);
/* integrator coeffs */
double[] cs; // displacement update coeffs
double[] ds; // velocity update coeffs
private double dt = 0.01;
private int upd_cnt = 0;
private void Awake()
{
if (Instance != null) {
// manager already init
Destroy(this);
return;
}
Instance = this;
DontDestroyOnLoad(Instance);
cs = new double[4] {0.5, 0.5*(1.0-c), 0.5*(1.0-c), 0.5};
ds = new double[4] {0.0, 1.0, -c, 1.0};
double divisor = 2.0 - c;
for (int i = 0; i < cs.GetLength(0); i++) {
cs[i] /= divisor;
ds[i] /= divisor;
}
}
public static void register_body(Sphere sphere)
{
bodies.Add(sphere);
}
double compute_accel(double x)
{
double k_by_m = 1; // k / m
return -k_by_m * x;
}
void FixedUpdate()
{
Sphere curr_body = bodies[0];
for (int i = 0; i < cs.GetLength(0); i++) {
double a = compute_accel(curr_body.r.x);
curr_body.v.x += (float) (ds[i] * a * dt);
curr_body.r.x += (float) (cs[i] * curr_body.v.x * dt);
}
upd_cnt += 1;
}
}
Sphere.cs:
public class Sphere : MonoBehaviour
{
// Start is called before the first frame update
public Vector3 v;
public Vector3 r;
void Start()
{
v = Vector3.zero;
r = transform.position;
}
void FixedUpdate()
{
transform.position = r;
}
}
