Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Position is not changing in loop?

Discussion in 'Scripting' started by Jadecraft4, Aug 8, 2020.

  1. Jadecraft4

    Jadecraft4

    Joined:
    Mar 1, 2020
    Posts:
    27
    I made a save and load system to save the positions of multiple objects and my problem is my gameobjects don't move in the loop when you load.
    Code (CSharp):
    1.  public GameObject[] objects;
    2.     [HideInInspector]
    3.     public List<float> ObjectID = new List<float>();
    4.     [HideInInspector]
    5.     public List<float> Xs = new List<float>();
    6.     [HideInInspector]
    7.     public List<float> Ys = new List<float>();
    8.     [HideInInspector]
    9.     public List<float> Zs = new List<float>();
    10.     public List<Vector3> Positions = new List<Vector3>(); //  for debuging
    11. // my load function
    12. public void Load()
    13.     {
    14.         // destroy all objects in scene
    15.         if (GameObject.FindGameObjectsWithTag("Object").Length != 0)
    16.         {
    17.             GameObject[] objects = GameObject.FindGameObjectsWithTag("Object");
    18.             for (int i = 0; i < objects.Length; i++)
    19.             {
    20.                 Destroy(objects[i]);
    21.             }
    22.         }
    23.         SaveData data = SaveSystem.LoadPlayer(); // Save data
    24.         ObjectID = data.ObjectID; // Which object to instanciate from objects
    25.         Xs = data.Xs; // all objects x coordinate
    26.         Ys = data.Ys; // all objects y coordinate
    27.         Zs = data.Zs; // all objects z coordinate
    28.  
    29.  
    30.         foreach (int ID in ObjectID)
    31.         {
    32.             // in the foreach to not instanciate a lot of them
    33.             GameObject NewGameobject = Instantiate(objects[ID], new Vector3(0, 0, 0), Quaternion.identity) as GameObject;
    34.             for (int i = 0; i < ObjectID.Count; i++)
    35.             {
    36.                 Positions.Add(new Vector3(Xs[i], Ys[i], Zs[i])); // making new position
    37.                 Debug.Log(Positions[i]); // positions are changing
    38.                 NewGameobject.transform.position = Positions[i]; //TRYING TO SET POSITION!!!
    39.             }
    40.         }
    41.     }
    Any help is appreciated.
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,723
    This code looks really fishy:

    Code (CSharp):
    1.         foreach (int ID in ObjectID)
    2.         {
    3.             // in the foreach to not instanciate a lot of them
    4.             GameObject NewGameobject = Instantiate(objects[ID], new Vector3(0, 0, 0), Quaternion.identity) as GameObject;
    5.             for (int i = 0; i < ObjectID.Count; i++)
    6.             {
    7.                 Positions.Add(new Vector3(Xs[i], Ys[i], Zs[i])); // making new position
    8.                 Debug.Log(Positions[i]); // positions are changing
    9.                 NewGameobject.transform.position = Positions[i]; //TRYING TO SET POSITION!!!
    10.             }
    11.         }
    Teh way you have this structured with the inner loop, bad things are going to happen:

    For every object you instantiate, you're adding EVERY position from your position arrays into the Positions list. and then you are setting NewGameobject.transform.position to every position in the list from 0 to ObjectID.Count.

    At the end of this you will end up in this state:

    • You will have ObjectID SQUARED number of Vector3s in your Positions list
    • Every new GameObject you instantiate will have Positions[ObjectID.Count - 1] as its position (because this is what it will be set to on the last iteration of the inner loop. They will all have the same position!
    That can't be right. What are you actually trying to do?
     
  3. Jadecraft4

    Jadecraft4

    Joined:
    Mar 1, 2020
    Posts:
    27
    I'm trying to get the instanciated object to go to it's saved position. The first loop gets the object's id and instantiate the saved object. Since every saved object has a saved X, Y, and Z (like the saved object is in objectID 0 and it's position is in x's, y's, and z's 0) I tried to make the object go to it's position.
     
  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,723
    Why not just do this?
    Code (CSharp):
    1.         for (int i = 0; i < ObjectID.Count; i++)
    2.         {          
    3.             Vector3 savedPosition= new Vector3(Xs[i], Ys[i], Zs[i]);
    4.             GameObject NewGameobject = Instantiate(objects[ObjectID[i]], savedPosition, Quaternion.identity) as GameObject;
    5.         }
    By the way using floating point numbers as IDs is very unusual.
     
    Last edited: Aug 8, 2020
  5. Jadecraft4

    Jadecraft4

    Joined:
    Mar 1, 2020
    Posts:
    27
    Uhhhh. I got this error. Error.PNG
    if I do this in a for loop then it goes in the right position, just the wrong object was instanciated.
     
  6. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,723
    Sorry, I made a typo, should be a normal for loop. Corrected above.
     
  7. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,723
    Post your updated code?
     
  8. Jadecraft4

    Jadecraft4

    Joined:
    Mar 1, 2020
    Posts:
    27
    Now it says cannot convert type 'float' to 'int' Error2.PNG

    also tried to fix it
    Code (CSharp):
    1. for (int i = 0; i < ObjectID.Count; i++)
    2.         {
    3.             Vector3 savedPosition = new Vector3(Xs[i], Ys[i], Zs[i]);
    4.             GameObject NewGameobject = Instantiate(objects[i], savedPosition, Quaternion.identity) as GameObject;
    5.         }
     
  9. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,723
    Why is your ObjectID list a list of
    float
    instead of
    int
    ? Is that intentional?
     
  10. Jadecraft4

    Jadecraft4

    Joined:
    Mar 1, 2020
    Posts:
    27
    I like floats more. should I change it? All I know is floats can have a decimal and ints cannot (I think, never really learned the difference)

    edit: changed to int and it worked! Thank You!!!
     
    Last edited: Aug 8, 2020
  11. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,723
    That's true, but for Array and List indexes you must use int. It doesn't really make sense to use float for discrete elements like that. Also float is subject to rounding errors and such.

    I'm a bit confused by your whole situation here. Why are you destroying the objects and then trying to immediately Instantiate them again?

    Why does it seem like you're loading a list of object IDs from a save data somewhere, but then you're actually getting your list of objects to instantiate from
    FindGameObjectsWithTag
    . By the way that method will not always return the objects in the same order so even if you get this working here now, it will probably break when you build the game for a platform.

    Anyway you can probably just cast your floats to ints, but this is all asking for trouble:

    Code (CSharp):
    1. for (int i = 0; i < ObjectID.Count; i++)
    2.         {
    3.             Vector3 savedPosition = new Vector3(Xs[i], Ys[i], Zs[i]);
    4.             GameObject NewGameobject = Instantiate(objects[(int)ObjectID[i]], savedPosition, Quaternion.identity) as GameObject;
    5.         }
     
  12. Jadecraft4

    Jadecraft4

    Joined:
    Mar 1, 2020
    Posts:
    27
    I'm destroying the objects in the scene so when you load the gameobjects, there aren't duplicates. there was a bug where when I pressed load multiple times it would make duplicates. Also if you placed anything, then loaded, it would get rid of it.