- Home /
Populate array on Start() and accessing it on Update()...how to?
So I'm a little stuck on this one... I'm populating an array of children and storing their starting position in the Start() function, but when I try to access the position of each of them in the Update() function, it only returns the position of the last object in the array.
Here's my code below:
using UnityEngine; using System.Collections;
// Remove warnings... #pragma warning disable 0219
public class ReloadTrack : MonoBehaviour {
// Define variables...
private Transform bike;
private float bikeCurrentPos;
private Vector3 clonePosition = new Vector3 (0,0,0);
private Quaternion cloneRotation;
public Vector3 cloneDistance;
private bool cloneExist;
private Vector3 finishPos;
public int numberOfLaps = 5;
private int currentLap;
// Define arrays...
private GameObject[] sceneObjects;
private Transform[] allChildren;
void Start () {
// Cache bike transform...
bike = GameObject.FindWithTag ("Bike").transform;
// Cache finish position...
finishPos = transform.position;
// Start at lap 1...
currentLap = 1;
// Cache all parent gameObjects in scene which have the "Clone" tag
sceneObjects = GameObject.FindGameObjectsWithTag ("Clone");
foreach (GameObject go in sceneObjects) {
allChildren = go.GetComponentsInChildren<Transform> ();
for (int i = 1; i < allChildren.Length; i++) {
clonePosition = allChildren[i].position;
cloneRotation = allChildren[i].rotation;
}
}
}
void Update () {
foreach (GameObject go in sceneObjects) {
allChildren = go.GetComponentsInChildren<Transform> ();
for (int i = 1; i < allChildren.Length; i++) {
Debug.Log (clonePosition);
}
}
}
So "clonePosition" in Start() returns the position of every object in the array "allChildren[i]", but when I debug it in Update(), it returns the position of the last object it cached on Start() for every single object.
My question is, how can I define "clonePosition" in Start() and access all its values in Update() without having to define it again? Thanks!
Not sure, I see it in most scripts so I just put it in $$anonymous$$e :) I don't know much about it so I copy what I see. Why shouldn't I use it?
Answer by Jessy · Jan 11, 2011 at 09:09 AM
clonePosition is a Vector3. You need some kind of proper storage for it (array / List); a Vector 3 is not appropriate, because you're just overwriting it a whole bunch with the code you have. Here's one way to go about it:
struct CloneChildAtStart { Vector3 position; Quaternion rotation;
public CloneChildAtStart (Vector3 position, Quaternion rotation) {
this.position = position;
this.rotation = rotation;
}
} List<List<CloneChildAtStart>> clonesChildrenAtStart;
void Start () { clonesChildrenAtStart = new List<List<CloneChildAtStart>>(); List<CloneChildAtStart> cloneChildrenAtStart = new List<CloneChildAtStart>(); foreach (GameObject clone in GameObject.FindGameObjectsWithTag("Clone")) { cloneChildrenAtStart.Clear(); foreach (Transform child in clone.transform) cloneChildrenAtStart.Add(new CloneChildAtStart(child.position, child.rotation)); clonesChildrenAtStart.Add(cloneChildrenAtStart);
} }
void Update () { for (int i = 0; i < clonesChildrenAtStart.Count; ++i) for (int j = 0; j < clonesChildrenAtStart[i].Count; ++j) Debug.Log(clonesChildrenAtStart[i][j]); }
I don't think the OP is trying to store all the positions, just extract them one at a time for logging. (I could be wrong ...)
Actually yes I am trying to store all the positions, so that I can later extract them without having to write the same for loops in Update.
I'm rather new to coding, so I'm not yet familiar with "struct" and "List" so I'm gonna look into it and try to understand Jessy's code above and use it for my needs, because from what I understand so far it is exactly what I need to do. Thanks!!!
A struct is a compact data structure, well-suited to storing unchanging data, like I think you're asking for here. A List is like an array, but generally much easier to work with. I made a List of Lists in the code above, because you need a list of "clones", each with their associated children.
Answer by yoyo · Jan 11, 2011 at 09:11 AM
You just need to add this in your second loop (in Update) ...
clonePosition = allChildren[i].position;
Also note that arrays in C# are indexed from 0, not 1, so your loop counters need to start at 0.
(And since you use allChildren and clonePosition in local scope, they don't need to be declared at the script level, but could be just local variables inside Start and Update.)
I figured he was starting at 1, because index 0 is the Transform itself, when you use GetComponentsInChildren.
Answer by ronronmx · Jan 19, 2011 at 09:24 PM
So after multiple (failed) attempts and lots of trial and error, I realized I was having the same problem with the code above as I did with my old code.
It stores all of the children's positions and rotations in Start, but when I try to access them in Update, "clonesChildrenAtStart[i][j]" only returns the last stored child and not all of them.
It won't let me access child 1-2-3-4....unless I write the same foreach loop in update as I did on Start, which is exactly what I was trying to avoid.
I'm pretty confused at this point, I'm not sure I'm expressing what I need correctly and I don't know what else to try. I don't understand how I can extract all the stored positions one at a time in Update, without having to store them beforehand in Update, but only in Start?
Answer by pixelmixer · Jan 19, 2011 at 10:23 PM
The reason you're only seeing the last child when you Log clonePosition is because in your Start loop each time it loops through you are overwriting the previously set clonePosition value. This essentially negates anything you are doing in your Update loop, and thus won't work.
I would store that clonePosition value in another array, then loop through that array later in your Update.
For example...
private Vector3 clonePosition[]; private Vector3 cloneRotation[];
foreach (GameObject go in sceneObjects) { allChildren = go.GetComponentsInChildren<Transform> (); for (int i = 1; i < allChildren.Length; i++) { clonePosition.Add(allChildren[i].position); cloneRotation.Add(allChildren[i].rotation);
} }
then later in Update you can do something like this...
foreach (Vector3 vect in clonePosition) { Debug.Log(vect); }
foreach (Vector3 vect in cloneRotation) { Debug.Log(vect); }
You could even go further and optimize that more to include Position and Rotation in a multidimensional array in order to access it later in Update.
Pixelmixer, thanks a lot for your help. About the multidimensional array, I think that's what Jessy try to do with his code above, by creating a "List", where "ChildObj" is a struct...but I'm not yet very familiar with structs and classes, so ho do you suggest I create a multidimensional array (or List) using a struct to store position and rotation?