Infinite Loop? when Setting Parent
I'm running into an issue that I can't seem to figure out, though I'm sure it's probably something simple. Setup is an attempt to make a modal dialog box. I had a yes/no working, and I've duplicated that and started working on one that allows you to choose something. There is a panel (dialogObject in code below) that covers all UI, a child panel that takes up about 80% of the visible space (the actual dialog), and a grandchild panel (cardSpread below) containing a gridbaglayout inside that.
The goal of this code is to remove what was in the previous iteration of this dialog (it's a static), and replace it with new collection. Everything works, up until I try to set the parent of the newly created object to the panel with the gridbaglayout. At that point, it seems to enter a infinite loop; memory usage skyrockets to about 98% of my cpu, unity freezes, and I have to use Task Manager to kill it.
So, I guess the question is -- what am I doing wrong? This doesn't look like it's any different than things I've done before.
Transform cardSpread = dialogObject.transform.Find ("Panel/CardSpread");
// Delete all old children
while (cardSpread.transform.childCount > 0)
{
GameObject.Destroy (cardSpread.GetChild (0).gameObject);
}
// Add new children
foreach (CardData data in cardReference)
{
Debug.Log ("Told to show card " + data.cardName);
GameObject go = GameObject.Instantiate (cardPrefab);
CardController cc = go.GetComponent<CardController> ();
cc.CardInfo = data;
if (go.transform == null)
Debug.Log ("Transform is null"); // Does not get triggered.
if (go.transform.parent == null)
Debug.Log ("Parent is null"); // Does get triggered.
//Debug.Log (go.transform.parent.name);
Debug.Log (cardSpread.name); // Properly shows "CardSpread"
go.transform.SetParent (cardSpread); // This line causes issue
Debug.Log ("Card should now be shown");
}
Answer by TBruce · Jun 21, 2016 at 08:19 PM
It would help to know what CardData looks like but I would start by making these changes
Transform cardSpread = dialogObject.transform.Find ("Panel/CardSpread");
// Delete all old children
for (int i = 0; i < cardSpread.childCount; i++)
{
if (cardSpread[i].childCount > 0)
{
GameObject.Destroy (cardSpread[i].GetChild(0).gameObject);
}
}
if (cardPrefab != null)
{
// Add new children
foreach (CardData data in cardReference) // here is the main problem
{
Debug.Log ("Told to show card " + data.cardName);
GameObject go = GameObject.Instantiate (cardPrefab);
if (go != null)
{
CardController cc = go.GetComponent<CardController> ();
if (cc != null)
{
cc.CardInfo = data;
if (go.transform.parent == null)
Debug.Log ("Parent is null"); // Does get triggered.
//Debug.Log (go.transform.parent.name);
Debug.Log (cardSpread.name); // Properly shows "CardSpread"
go.transform.SetParent(cardSpread, false); // This line causes issue
Debug.Log ("Card should now be shown");
}
else
{
Debug.Log ("Transform is null"); // Does not get triggered.
}
}
}
}
So, other than null checks (which I would have done eventually, once I got good-path working), all I see that you changed is adding a false to the SetParent, and you changed the way the children were being deleted. Neither of which are applicable to my question, I don't think -- though I am interested in the child-of-array delete you have there. Why would that be necessary? The Transform.Find returns a single Transform object as far as I've been able to deter$$anonymous$$e.
CardData is a 400-line class that stores data about the card (think mana cost in $$anonymous$$agic and the like), and calls Actions when needed. I've actually changed the assignment to a clone call since I posted hte question, but it didn't make a difference.
The main change I made was the Delete all old children loop.
while (cardSpread.transform.childCount > 0)
{
GameObject.Destroy (cardSpread.GetChild (0).gameObject);
}
The script above is your infinite loop because cardSpread.transform.childCount never changes.
I'm seeing debug logs from after that point in code, though.
Perhaps a better understanding of what you're saying would help me. I'm accessing cardSpread.transform.childCount to see how many objects are in the layout. Then, using cardSpread.GetChild (0).gameObject to destroy them. You changed that to elements of an array...but the only children of my panel are the objects I want to destroy:
.CardChooser
..Panel
...CardSpread
....Object1
....Object2
....Object3
Why would cardSpread.GetChild (0).gameObject NOT be referencing Object1? And why would cardSpread[i].GetChild(0).gameObject reference anything when it isn't an array?
Your answer
Follow this Question
Related Questions
Parenting an object causes it to change rotation 1 Answer
how to stop infinite jumping in air? 0 Answers
bullet holes parenting 1 Answer