My List is resetting to empty for no good reason
I have a private List of GameObjects that gets Added to when my space scene is initialised. There is nothing in my code removing or reducing the size of this list, but Debug.Logs of its .Count tell me it reverts to 0 Count after a frame. It's rather lengthy, but since people often ask to see code, here's my StarSystemDetails class: (The Update function is the one that Logs the Count and it is at the end of the class)...
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
public class StarSystemDetails : MonoBehaviour {
public GameObject sun; // <<<<<<<<<<<<<<<<<<< prefab passed in from Unity Editor
public int _numberOfPlanets;
public int _planetCounter = 0;
private int _numberOfPopulations = 0;
private List<SystemBodyDetails> _systemBodies = new List<SystemBodyDetails>();
private List<GameObject> _systemGameObjects = new List<GameObject>();
private Vector3 _coordinates;
public GameObject planet;
private List<Texture> _textures;
private float _satelliteSpacing;
private bool _habitableBodyGenerated=false;
private SystemBodyDetails _nextHabitable;
private float _suitability=0;
private bool _fullyPopulated = false;
private float _civilianSettlers;
private float _militarySettlers;
private GameObject _nearestGravityWell;
// class constructor
public StarSystemDetails() {
}
public Vector3 coordinates {
get {
return _coordinates;
}
}
public bool fullyPopulated {
get {
return _fullyPopulated;
}
}
public void Init(string p_name, List<Texture> p_textures) {
_coordinates = new Vector3( ((RandomSeed.getInstance().unit*1000000)-500000), ((RandomSeed.getInstance().unit*500000)-250000), ((RandomSeed.getInstance().unit*1000000)-500000) );
float _orbitDistance = 0;
SystemBodyDetails _sunDetails = new SystemBodyDetails(this, null, 0); // SystemBodyDetails should know that 0 orbital distance makes this new object the sun
_systemBodies.Add(_sunDetails);
float nonCeilNumberOfPlanets = (float)( (RandomSeed.getInstance().unit + 0.5) * 2 ) + Mathf.Sqrt( ( _systemBodies[0].radius + 500000 ) / 120000 );
_numberOfPlanets = (int)(Mathf.Ceil( nonCeilNumberOfPlanets ) + 3f);
Debug.Log("StarSystemDetails.Init _numberOfPlanets = "+_numberOfPlanets);
for (int k = 0; k < 15000; k++) {
if ( _orbitDistance == 0 && ( _systemBodies[0].heat/Mathf.Sqrt( k*1000000 ) ) < 1000 ) {
_orbitDistance = k * 1000000;
}
}
if (_orbitDistance==0) {
//trace(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> heat never matched >>>>>>>>>>>>>");
_orbitDistance = ((_systemBodies[0].radius+1000000)*5)*(2+(RandomSeed.getInstance().unitAverage * 4));
}
Debug.Log("StarSystemDetails.Init planet = "+planet);
name = p_name;
_textures = p_textures;
// add planets
for (int x = 0; x < _numberOfPlanets; x++) {
_planetCounter ++;
SystemBodyDetails _systemBodyDetails = new SystemBodyDetails(this, _systemBodies[0], _orbitDistance);
_systemBodies.Add(_systemBodyDetails);
_orbitDistance += 200000000;
_systemBodies[x].planetInitialName = p_name; // this setter function messes with the passed system p_name
}
// add planets' moons
for (int x = 1; x <= _numberOfPlanets; x++) {
_satelliteSpacing = 40000 + (_systemBodies[x].radius * 4 * RandomSeed.getInstance().unit) + (_systemBodies[x].radius);
_planetCounter = 0;
for (int y = 0; y<_systemBodies[x].numberOfSatellites; y++) {
_planetCounter += 1;
SystemBodyDetails _systemBodyDetails = new SystemBodyDetails(this, _systemBodies[y], -1);
_systemBodies.Add(_systemBodyDetails);
_systemBodies[x].satelliteInitialName = p_name; // this setter function also messes with the passed system p_name
}
}
}
public void instantiateSystemGameObjects() {
// first, add sun...
GameObject newSun = Instantiate(sun) as GameObject;
_systemGameObjects.Add(newSun);
newSun.GetComponent<SystemBody>().Init(_systemBodies[0], null);
// then, add planets and moons...
for (int x = 1; x < _systemBodies.Count; x++) {
GameObject newPlanet = Instantiate(planet) as GameObject;
Debug.Log("new planet = "+newPlanet);
_systemGameObjects.Add(newPlanet);
// pass correct SystemBodyDetails into newPlanet...
newPlanet.GetComponent<SystemBody>().Init(_systemBodies[x], _textures);
}
_nearestGravityWell = _systemGameObjects[1];
}
public SystemBodyDetails mostHabitableBody {
get {
SystemBodyDetails mostHabitable;
float highestHabitability = 0.2f;
int mostHabitableIndex = 0;
for (int x = 1; x < _systemBodies.Count; x++) {
if (_systemBodies[x].habitability>highestHabitability && _systemBodies[x].population==null) {
Debug.Log(_systemBodies[x].name+"'s habitability = "+_systemBodies[x].habitability);
highestHabitability = _systemBodies[x].habitability;
mostHabitableIndex = x;
}
}
if (mostHabitableIndex==0) {
_fullyPopulated = true;
return null;
}
mostHabitable = _systemBodies[mostHabitableIndex];
return mostHabitable;
}
}
public SystemBodyDetails mostMilitaryBody(float p_suitabilityThreshold=0.06f) {
_suitability = p_suitabilityThreshold;
_nextHabitable = null;
for (int i=1;i<_systemBodies.Count;i++) {
if ( _systemBodies[i].profitability<0.06 && _systemBodies[i].habitability>_suitability && _systemBodies[i].populationNumber==0 && _systemBodies[i].habitable) {
_suitability=_systemBodies[i].habitability;
_nextHabitable=_systemBodies[i];
}
}
return _nextHabitable;
}
public SystemBodyDetails mostMinableBody(float p_suitabilityThreshold=0.06f) {
_suitability = 0;
_nextHabitable = null;
for (int i=1;i<_systemBodies.Count;i++) {
if ( _systemBodies[i].profitability<0.06 && _systemBodies[i].profitability>p_suitabilityThreshold && _systemBodies[i].rawResources>_suitability && _systemBodies[i].populationNumber==0 && _systemBodies[i].habitable) {
_suitability=_systemBodies[i].rawResources;
_nextHabitable=_systemBodies[i];
}
}
return _nextHabitable;
}
public void newStarSystemSought(SystemBodyDetails p_sourceBody, float p_currentDate) {
p_sourceBody.population.parent.newStarSystemSought(p_sourceBody, p_currentDate); // this is slightly convoluted but I don't currently care...
}
public void newSystemBodySought(SystemBodyDetails p_sourceBody, float p_currentDate) {
SystemBodyDetails tempBody=null;
Settlers newSettlers;
if (p_sourceBody.settlementType=="Colony") {
tempBody = mostHabitableBody;
_civilianSettlers = 10000;
_militarySettlers = 5000;
} else if (p_sourceBody.settlementType=="MilitaryBase") {
tempBody = mostMilitaryBody(0.01f);
_civilianSettlers = 0;
_militarySettlers = 1000;
} else if (p_sourceBody.settlementType=="Mine") {
tempBody = mostMinableBody(0.02f);
_civilianSettlers = 1500;
_militarySettlers = 100;
}
if (tempBody!=null) {
newSettlers = p_sourceBody.getSettlers(_civilianSettlers, _militarySettlers);
p_sourceBody.population.parent.settlePopulation(tempBody, newSettlers, p_currentDate, p_sourceBody.settlementType);
p_sourceBody.addHistoricEvent(p_currentDate, ": Settled "+tempBody.localName);
}
}
public int numberOfPopulations {
get {
return _numberOfPopulations;
}
set {
_numberOfPopulations = value;
}
}
public GameObject nearestGravityWell {
get {
return _nearestGravityWell;
}
}
public bool populated {
get {
return _numberOfPopulations>0;
}
}
public List<SystemBodyDetails> systemBodyDetails
{
get {
return _systemBodies;
}
}
public List<GameObject> systemGameObjects
{
get {
return _systemGameObjects;
}
}
public int planetCounter
{
get {
return _planetCounter;
}
}
public float satelliteSpacing {
get {
return _satelliteSpacing;
}
}
public void Update() {
/*_systemGameObjects.Sort( delegate(GameObject c1, GameObject c2){
return c1.transform.position.sqrMagnitude.CompareTo(c2.transform.position.sqrMagnitude);
} );*/
Debug.Log("StarSystemDetail.Update _systemGameObjects.Count = "+_systemGameObjects.Count);
_nearestGravityWell = _systemGameObjects[1];
Debug.Log("StarSystemDetails.Update _nearestGravityWell = "+_nearestGravityWell);
/*if (_nearestGravityWell==null) {
Debug.Log("_nearestGravityWell set to null - why?");
Application.Quit();
}*/
}
}
Like I said, I see nowhere where this List is reduced to 0. Does anyone have any idea why this might be happening? I've wasted most of today trying to isolate it. (I have commented out sections of code just to isolate where the problem is happening).
Thanks.
O$$anonymous$$, I've added a second list _hiddenSystemGameObjects, which has NO getter method and is referred to ONLY in the GameObject instantiation method and Update. It STILL gets reduced to 0 Count. Wha? Anyone have a clue as to why this is happening? Is there some special property on Lists that I need to set to prevent them emptying each frame? (I know that's unlikely, but that's what's happening!). Gah!
In addition to the comment above, I've noticed that, no matter how long I test the game for in Unity, in the console, there's always the same PROPORTION of Log calls with the Count displayed correctly vs Log calls with the Count reset to 0. It's always a fifteenth. HOW does this make any sense?! How would the correctly populated list persist for an amount of time dependent on how LONG I'm letting the game run for? This is officially beginning to do my head in. Any help well appreciated...
Answer by jmonasterio · Dec 29, 2015 at 12:19 AM
Are you sure you don't have more than one StarSystemDetails component in your scene? Maybe one of them is different than the other.
StarSystemDetails is a component of the prefab StarSystem GameObject. I had been generating 16 of them. I've just tried reducing the number of star systems to 12 and, of course, the proportion of Log calls changes to 11. So it's the star systems that don't get their GameObjects created that are producing the empty List Log calls, not the star system the player is seeing. So I wasted yesterday, basically. Thanks for the clue!