I'm currently working on an N-Body Simulation to try out some new things, one of which being the event system in Unity. The problem I'm facing is, although it once worked ( I believe perfectly ), it now only activates around 60 times. What I'm doing is spawning a given amount of Planets in a loop, each time this happens an Event is triggered which sends the current planet's GameObject to a different script which adds it to a List so that it knows on which GameObjects it needs to do calculations. Here are the two important snippets of code:
public class PlanetSpawnHandler : MonoBehaviour
{
public int startPlanetCount;
public float spawnRadius;
public GameObject planetPrefab;
public float startForce;
GameObject[] sunArray;
//Event and EventArgs
public event EventHandler<OnPlanetSpawnedArgs> OnPlanetSpawned;
public class OnPlanetSpawnedArgs : EventArgs
{
public GameObject planetArg;
}
//Start is called before the first frame update
void Start()
{
sunArray = GameObject.FindGameObjectsWithTag("Sun");
foreach (GameObject sun in sunArray)
{
OnPlanetSpawned?.Invoke(this, new OnPlanetSpawnedArgs { planetArg = sun });
}
for (int o = 0; o < sunArray.Length; o )
{
float x = sunArray[o].transform.position.x;
float y = sunArray[o].transform.position.y;
float z = sunArray[o].transform.position.z;
for (int i = 0; i < startPlanetCount; i )
{
//Calculations for Planet Spawning
Vector3 instantiatePos = new Vector3(x - UnityEngine.Random.Range(-spawnRadius, spawnRadius), y - UnityEngine.Random.Range(-spawnRadius, spawnRadius), z - UnityEngine.Random.Range(-spawnRadius, spawnRadius));
GameObject planet = Instantiate(planetPrefab, instantiatePos, Quaternion.identity);
Rigidbody rb = planet.GetComponent<Rigidbody>();
rb.AddForce(startForce * rb.mass, startForce * rb.mass, startForce * rb.mass);
//Triggering the Event
OnPlanetSpawned?.Invoke(this, new OnPlanetSpawnedArgs { planetArg = planet });
//Debug.Log("Spawned Planet");
}
}
}
And the listener:
public class Attraction: MonoBehaviour
{
List<GameObject> planetList = new List<GameObject>();
private void OnEnable()
{
//Subscribing to Event
PlanetSpawnHandler planetSpawnHandler = GetComponent<PlanetSpawnHandler>();
planetSpawnHandler.OnPlanetSpawned = AddPlanetToList;
//Debug.Log(planetSpawnHandler);
}
// Update is called once per frame
private void FixedUpdate()
{
//Shitty code, pls ignore
foreach (GameObject planet in planetList)
{
if (planet == null)
continue;
else
{
foreach (GameObject otherPlanet in planetList)
{
if (planet == otherPlanet)
continue;
else
{
if (otherPlanet == null)
continue;
else
{
Rigidbody planetRb = planet.GetComponent<Rigidbody>();
Rigidbody otherPlanetRb = otherPlanet.GetComponent<Rigidbody>();
Vector3 direction = planetRb.position - otherPlanetRb.position;
float distance = direction.magnitude;
float forceMagnitude = (planetRb.mass * otherPlanetRb.mass) / Mathf.Pow(distance, 2) * 1000f;
Vector3 force = direction.normalized * forceMagnitude;
otherPlanetRb.AddForce(force);
}
}
}
}
}
}
//Function for Event
public void AddPlanetToList(object sender, PlanetSpawnHandler.OnPlanetSpawnedArgs planet )
{
Debug.Log("AddPlanet called");
planetList.Add(planet.planetArg);
Debug.Log(planetList.Count " In List");
}
As I said, the problem is that the listener only receives 60 messages from the Publisher, although I'm sure it once worked perfectly.
If you need any other information, tell me and I will provide it
CodePudding user response:
The problem has been resolved, issue was with a different script for some reason
CodePudding user response:
Your listener has a function, FixedUpdate
, with a comment above it saying Update is called once per frame
. Your comment no longer matches the function you're using.
You want to change that function to Update
instead:
// Update is called once per frame
private void Update()
{
...
}
FixedUpdate
is for frame-independent calculations, and is called 60 times per second. Note that physics calculations often make use of Time.fixedDeltaTime
in this function, if that's relevant to you.
Update
is called once per frame and usually uses Time.deltaTime
.