unable to do foreach loop (Solved)

hello there. i´m working on a project. i´m trying to do some sort of save game mechanism but it´s not really working for me.
the simple idea i have is to do a for loop which finds and stores all gameobjects with a specific tag in a array.
to make it more robust i want to do a foreach loop and add all the transforms to a generic list.

however, my foreach loop does not work. also is there another more beneficial way of doing this ? could i even skip the transform step and just store all the gameobjects in the array an just save it to a file ?

using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public class manager : MonoBehaviour {

    public static int  i;
    int j;
    public GameObject[] array;
//    public Transform[] posArray;
    public  List<Transform> ListPos = new List<Transform>();

    public GameObject sphere;
    public GameObject cube;
    int count;
    // Use this for initialization



    void Start () {

    }
   
    public void addobjects()
    {
       

        for (j = 0; j <4; j++)
            {

            GameObject[] array = GameObject.FindGameObjectsWithTag ("Player");

            
            print ("objects in array:"+array[j]);

            }   

    }

    void Update () {
       

    }

    public void showdata()
    {

        foreach(GameObject go in array)
        {
            print ("is working");
        }

    }

  }

Why are you declaring these variables like ‘i’ and ‘j’ as fields?

Also, your code won’t compile because you have declared a GameObject array named ‘array’ as a class member, but then redeclare it inside the method ‘addobjects’.

There’s a bunch of issues above. The code isn’t really doing anything unless you call one of those methods externally anyway so maybe thats your problem. But other than that of course you have some scope problems that wouldn’t allow it to compile so I think you kind of need to throw this into Visual Studio or something so you can get feedback on issues that are holding you back from actually doing anything to begin with.

For or Foreach loops are both fine, but you might use For so you could have the iterator (your j, defined out of scope for no reason.) while Foreach is nice if you want a reference to the object being iterated. It just depends on your application.

For loop iterators are almost always defined in the For arguments. Here’s a quick example.

    public void Start()
    {
        GameObject[] array = GameObject.FindGameObjectsWithTag("Player");

        for (int i = 0; i < array.Length; i++)
        {
            Debug.Log("Looping Item: " + i);
        }

        foreach (GameObject go in array)
        {
            Debug.Log("Looping Item: " + go.name);
        }
    }

For loops break down like this:

for (int i = 0;
define the iterator, typically just called ’ i '.

for (int i = 0; i < array.length;
the condition for completion, if this is true then the For loop will continue and process the next argument, when this evaluates to false then it will finish the loop.

for (int i = 0; i < array.length; i++)
i++ means add 1 to the variable, so i will be increased by 1 if the condition was true.

** **for (int i = 0; i < array.length; i++) { // stuff you want to do each time the condition is true. for example.. array[i].name = "Found and Processed"; }** **

here we used the iterator in the For loop to access part of the array and do something to each item in it.

Theres some technical explanations about it online of course, but that’s just a quick explanation.

thank you very much for your quick replies :slight_smile:
well the reason why i declare my variables as fields is because when i started to learn how to program in c a year ago i was taught to do it this way. and later when i moved on to c# it kinda stuck with me. also there´s nothing wrong in declaring variables this way.
also, the reason why i declare the array first as a classmember is because i assumed that you declare it that way, i took it from the examples i have read so i assumed this was the correct way to do it.

the methods i am calling is being triggered by Gui buttons, so if i press the addobjects button it´s gonna execute the addobjects method.

thank you for the example, i will try and implement it in my project,

Yes there is… there’s a lot wrong with your field declarations.

For one, making them class member fields, they persist for the life of the object on the heap, rather than for the life of the function on the stack where they’re only needed. Note… C is not object oriented, and is procedural by nature… this is NOT C.

There’s other issues, lets go through them one by one.

public static int  i; //why is this static? Do you understand what static is for?
int j; //you are explicit with access modifiers sometimes, but not others? Be consistent
public GameObject[] array; //what an attrocious name for a variable, be more descriptive
public  List<Transform> ListPos = new List<Transform>(); //So you decided this type deserved an uppercase for its first letter???
//and it's unused

public GameObject sphere; //unused anywhere in your code... what's the point?
public GameObject cube; //also unused, what is the point?
int count; //access modifier, bad name, and it's also unused...

You assumed?

And you reassert it’s right based on that assumption despite us saying “huh, why do you do that?”

Oh, and that static member… that one is a doozy. You do understand what static does right? That variable persists in memory for the life of the entire program (even if no ‘manager’ objects exist). Furthermore, anytime your loop runs, its using this shared variable… if any other code manipulates it (including other instances of ‘manager’) it will screw up all managers.

1 Like

Just to make sure it’s understood, your foreach loop isn’t doing anything because your for loop didn’t put anything in your array array (Really, bad naming there…), so there were 0 items for the foreach to go through.

Hi, i have worked on the code now at everything works now :slight_smile:
i´m successfully able to load my gameobjects to my array and then instantiate from my list.
i understand my code was confusing and didn´t make sense because i often leave a lot of variables and stuff from my previous attempts. usually when everything works i begin cleaning up the code.

now that i got this working i still got at problem.
after adding my gameobjects to my array and lists, i want to remove the gameobjects in my scene and then instantiate them from my lists still with their positions intact. unfortunately i am getting an error saying : the object of type “Gameobject” has been destroyed but you are trying to access it.
why does it remove my data from my lists when i delete the gameobjects ?
here´s my code:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public class manager : MonoBehaviour {

   
    int i;
    public  List<Transform> ListPos = new List<Transform>();
    public  List<GameObject> objlist = new List<GameObject>();


    void Start () {

    }
   
    public void addobjects()
    {
        GameObject[] objects = GameObject.FindGameObjectsWithTag ("Player");

        for (i = 0; i <objects.Length; i++)
            {

        //    print ("objects in array:"+array[j]);

            }   
        foreach(GameObject go in objects)
        {
            ListPos.Add (go.transform);
            objlist.Add (go);
        //    print ("objects in list:"+ListPos.Count);
   
        }
    }

    void Update () {
       

    }

    public void showdata()
    {

        for (i = 0; i <ListPos.Count; i++)
        {
            print ("objects in list:"+ListPos.Count);

        }

    }

    public void load()
    {

        for (i = 0; i < ListPos.Count; i++)
        {

            Instantiate(objlist[i], objlist[i].transform.position, Quaternion.identity);
        }
 
       
    }

    public void delete()
    {
        Destroy(GameObject.FindGameObjectWithTag("Player"));
    }
}

You very obvsly came from C…

C# is heavily object oriented.

When you put your gameobjects into the lists, you’re not COPYING them… you’re creating a new reference to them in that list.

Kind of like ‘pointers’ in C.

So when you destroy them, the references in the lists are pointing at the same objects still, so they’re now pointing at destroyed objects.

yeah i know c# is object oriented, i think there are a few basic things i need to learn before i move on to more difficult stuff.
thank you for the analogy with the pointers :wink:
i am not completely sure about how to do this saving data thing but this is an idea i got:

my game data (my lists) are saved to a file on disk
my game data are referenced into a new set of lists
in the load () i use the new lists. how does that sound ? would that work ?

So after got the foreach loop working, i began investigating how to serialize data and stuff like that. to my disappointment i learned that you can´t serialize gameobjects. rethinking this i decided to do an nested list, an list that contains transforms for each of the gameobjects in my array i want to save.
however, when i run my game i keep getting the error: “ArgumentOutOfRangeException: argument is out of range. Parameter name: index”
what am i doing wrong ?

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;


public class manager : MonoBehaviour {

   
    int i;
    List<Transform> ListPos = new List<Transform>();
    public     List<List<Transform>> DataList = new List<List<Transform>>();

    private    string filepath = @"C:\Users\Andreas\Documents\My Games\RTS Game";
    //public  List<GameObject> objlist = new List<GameObject>();

    void Start () {


   


    }
   
    public void addobjects()
    {
       


        GameObject[] objects = GameObject.FindGameObjectsWithTag ("Player");

    /*    for (i = 0; i <objects.Length; i++)
            {

            print ("objects in array:"+array[j]);

            }
    */

        foreach(GameObject go in objects)
        {
            if(go.name == "Sphere")
            {
                ListPos.Add (go.transform);   
                DataList.Insert (0,ListPos);
            }
            else if(go.name == "Cube")
            {
                ListPos.Add (go.transform);   
                DataList.Insert (1,ListPos);
            }
        }
    }

    void Update () {
       

    }

    public void showdata(List<List<Transform>> DataList)
    {

        print ("objcts in datalist:");
        foreach(var ListPos in DataList)
        {
            foreach(var transform in ListPos)
            {
                print (ListPos);
            }   
        }


    }
    /*
  
}

/*
[Serializable]
class PlayerData
{
//    public  List<Transform> Pos = new List<Transform>();
//    public  List<GameObject> Obj = new List<GameObject>();

}*/

Error line?

And it’s probably worth updating yourself on C# and forum conventions if you are coming to continue posting here. Variables declared in the wrong place, unusual capitalisation, inconsistent white space, empty methods and commented code all make things difficult to read.

Without a line number it’s hard to say, but I’m guessing it’s the line:
DataList.Insert (1,ListPos);

If the first object in “objects” is a cube, then it will try to insert that at the second position … before there even is a second position; hence the error.

However, I’m pretty sure that logic isn’t doing what you want anyway - you’re assigning the same inner List into the outer List a bunch of times, and Insert doesn’t put it “into” the element at that position, it puts it in the outer list right before that position (ie. it now occupies that index and whatever used to be there is now at index+1).

Your print statement is screwy also, since it’s looping through the inner list but then just printing the list itself (not the contents) repeatedly.

hello everyone, sorry for my Hiatus. i have been busy working on my game.
i can gladly tell you guys i got my save data class working. i have also begun cleaning up all my code and making it more consistent and i have learned a lot of stuff since i posted here.
So thank you guys for your help so far :slight_smile:

1 Like