- Home /
Hi, i have foreach on 30 GO's that twice a second,finds tags(cca100),so i was thinking of making a static List of those 100, find them at start , and then subtract accordingly,should i be aware of something?
because, 30 x 100 x 2 = a lot to do in a second.
What are you doing with those GameObjects? How are you doing a foreach? Are they already in a list? You said that your foreach loop is on 30 GameObjects, but then you are asking about making a list of 100. What do you mean by subtract? If you could provide a little more on what you want to do, that would help. But from what I understand so far, I imagine if you are looking just for a GameObject with a certain script, you can create a static list on that class and have each instance add or remove themselves on enable and disable. Then you could just get the static list where ever and do what you want with it. Hard to say more without understanding what you want. But yeah I imagine you can make a list of these somewhere. You will just have to be sure they remove themselves if they get disabled. I cant imagine needing to iterate that often...
well i have a turret script with Start(): invoke repeat every 0.5 second the foreaach loop. the foreach does: GameObject[] enemies = GameObject.FindGameObjectsWithTag ("Greens");---cca 100 of those GameObject[] enemies = GameObject.FindGameObjectsWithTag ("Reds");--- cca 100 of those GameObject[] enemies = GameObject.FindGameObjectsWithTag ("Greys");--- cca 100 of those. and this 3 lines are present on each turret, that is , cca 30,..
right now i made a static list , of those three lines,. and i am ins$$anonymous$$d of every 0.5 second of doing .findwithttag, doing foreach enemy in enemies.
Answer by Kciwsolb · May 07, 2018 at 04:43 PM
I think I understand enough to at least suggest an alternative. I still am not sure what you are doing with your objects once you find them, but you definitely don't need to find them all that many times. I would instead make a public static List of each type of enemies. Put these Lists on your Enemy class.
//On your Enemy class:
public static List<Enemy>() greenEnemies = new List<Enemy>(); //Replace "Enemy" with what ever you called it if it is different and repeat this line for each enemy color
Make one for each color of enemy. Then have a variable on your Enemy script called enemyColor.
public string enemyColor;
Then in OnEnable and OnDisable Add or Remove the instance from the appropriate List. This will prevent any problems if/when new enemies get spawned or destroyed.
private void OnEnable()
{
switch(enemyColor)
{
case "green":
greenEnemies.Add(this);
break;
//Repeat for all colors
}
}
private void OnDisable()
{
//The same thing except do Remove(this);
}
Then when you need to access these you will not need to call find each time. Instead, just access the static list from the class.
foreach(Enemy enemy in Enemy.greenEnemies)
{
//do stuff
}
There might be a more optimized way, but I don't know exactly what you need to loop through them for. But this will be A LOT better than doing a find twice a second.
its an updatetarget function for the turret to know whos closest
Oh. That helps. Does your turret have a max range? If so, ins$$anonymous$$d of checking ALL enemies (I assume many will be out of range) just do a OverlapCircleAll (assu$$anonymous$$g a 2D game) and check the returned array of Colliders to see if any of them are enemies. If they are, only check those ones for distance. This will elimanate checking enemies that are out of range. Read about OverlapCircleAll here: https://docs.unity3d.com/ScriptReference/Physics2D.OverlapCircleAll.html
If you do not have a max range, then you could still do it with static Lists like I suggested. Loop through each one and check for a closest enemy. I am not sure why color is relevant. If it isn't, then you could just have one list of enemies.
If you have too many enemies and this starts slowing things down, try moving your target checking function into a coroutine. That way it won't slow down everything else. You could have it call a change target function when it finishes finding the closest enemy.
Hope this helps! :D
oh , you mean like ::pseudo inco$$anonymous$$g:: : Coroutine (while) { overlapSphere.catchedColliders >0 } UpdateTarget(). else return;
? and colors = factions,for the sake of it.
private GameObject[] enemyReds;
private GameObject[] enemyGreens;
private GameObject[] enemyGreys;
private GameObject[] civs;
public static List<GameObject> L_enemiesRed = new List<GameObject>();
public static List<GameObject> L_enemiesGreen = new List<GameObject>();
public static List<GameObject> L_enemiesGrey = new List<GameObject>();
public static List<GameObject> L_Civs = new List<GameObject>();
void Start ()
{
GameObject[] enemyReds = GameObject.FindGameObjectsWithTag ("Reds");
GameObject[] enemyGreens = GameObject.FindGameObjectsWithTag ("Greens");
GameObject[] enemyGreys = GameObject.FindGameObjectsWithTag ("Greys");
GameObject[] civs = GameObject.FindGameObjectsWithTag ("Civs");
L_enemiesRed.AddRange (enemyReds);
L_enemiesGreen.AddRange (enemyGreens);
L_enemiesGrey.AddRange (enemyGreys);
L_Civs.AddRange (civs);
}
this is invoke every 0.5 on each(cca 30) turret
void UpdateTarget() {
float ShortDistance = $$anonymous$$athf.Infinity;
GameObject NearestEnemy = null;
foreach (GameObject enemy in Static_List.L_enemiesRed)
{
float DistanceToEnemy = Vector2.Distance (transform.position, enemy.transform.position);
if (DistanceToEnemy < ShortDistance)
{
ShortDistance = DistanceToEnemy;
NearestEnemy = enemy;
}
}
foreach (GameObject enemy2 in Static_List.L_enemiesGreen)
{
float DistanceToEnemy = Vector2.Distance (transform.position, enemy2.transform.position);
if (DistanceToEnemy < ShortDistance)
{
ShortDistance = DistanceToEnemy;
NearestEnemy = enemy2;
}
}
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Populating a list with multiple GameObjects 1 Answer
contents of a static list - see in editor 0 Answers
Static functions and lists not co-operating. 0 Answers
Static class member for offset 1 Answer