first of all thank you for your time and im sorry for both my english and my low skills. Basically im doing this endless runner, where the player moves forward and jump over stuff. To make it endless i made a script that randomly chooses a prefabbetween those i attached to the script, and spawns it at the end of the position (using an empty object) of the other platform spawned before. To reset the game after you lose, i need to remove all the platforms spawned and saved in the list, but my problem is that every once in a while the script will skip one of them causing it to remain after the reset and restart. here is my code:
public void Reset()
{
deathMenu.gameObject.SetActive(false);
for (int i = 0; i < generatore.getPooled().Count; i )
{
if (generatore.getPooled()[i] == null)
{
i ;
}
else
{
generatore.getPooled()[i].gameObject.SetActive(false);
if (!generatore.getPooled()[i].gameObject.activeInHierarchy)
{
Destroy(generatore.getPooled()[i].gameObject);
}
if (i > 0)
{
if (generatore.getPooled()[i - 1] == null && generatore.getPooled()[i 1] == null)
{
Destroy(generatore.getPooled()[i].gameObject);
}
}
}
}
player.transform.position = playerStartPoint;
generatore.SetEndPosition(endPosition);
player.gameObject.SetActive(true);
scoreManager.scoreCounter = 0;
scoreManager.scoreIncrease = true;
}
it basically gets the platforms of the list (generatore.getPooled()), sets them inactive and then removes them one by one. I had to set them inactive before removing them because for some reasons, it skips even more platforms if i only remove them , and i even tried to remove the ones that the script skips by adding:
if (generatore.getPooled()[i - 1] == null && generatore.getPooled()[i 1] == null)
{
Destroy(generatore.getPooled()[i].gameObject);
}
but it still skips them. Here is what i mean
CodePudding user response:
First of all why are you doing
i
inn the firstif
case inside the loop?Since
i
is done anyway after every iteration this skips not the current but the next item as well! You would rather want to usecontinue
instead.Then you are repeatedly calling
generator.getPooled()
which always returns a new list (I guess). This is not only bad performance wise but also while you remove entries from the pool (I suppose that somewhere happens while you destroy them) all other items most probably move one step up and thereby change their indices. So since you continuously increase the index
i
it might happen that an element was moved to an index you already passed so this again leads to skipping some of them.And then your conditions for calling
Destroy
are quite redundant. Right aftersomeGameObject.SetActive(false);
the check for
if(!someGameObject.activeInHierarchy)
will always be true (except there is some dark magic going on in a script where in
OnDisable
you set yourself to active again - which sounds pretty uncanny to do ^^).And since you destroy it anyway (see 3.) there actually is no need at all for setting it to inactive first.
And also since you will always destroy the object (see 3.) the next check via indices makes no sense since you already destroyed the object anyway.
So in summary your code would shrink down to
foreach (var pooled in generatore.getPooled())
{
if (!pooled) continue;
Destroy(pooled.gameObject);
}
// TODO: clear the pool so there are no null elements remaining forever
CodePudding user response:
you can assign a specific tag to your platforms
then try using a foreach loop for destroying them, like this:
foreach (GameObject platform4delete in
GameObject.FindGameObjectsWithTag("somePlatfromTag"))
{
Destroy(platform4delete);
}
it probably will delete all platforms without missing any