Author Topic: AddChild() not instantiating correctly in the hierarchy  (Read 7434 times)

TimL

  • Guest
AddChild() not instantiating correctly in the hierarchy
« on: December 31, 2013, 12:30:10 PM »
I am running into a bit of a problem using AddChild() to instantiate additional objects inside a scroll window. I am using the following code to populate a list of jobs in a Jobs Window:

  1.         // CreateJobs() is called to populate the job window.
  2.         private void CreateJobs(int numJobs) {
  3.                 grid = GameObject.Find("Jobs Grid");    // Locate the Jobs Grid for this job window and store it in grid.
  4.  
  5.                 for (int i = 0; i < numJobs; i++) {     // Repeat until numJobs has been reached...
  6.                         NGUITools.AddChild(grid, UIPackagePrefab);      // Create a package object and add it to the scene as a child of grid.
  7.                 }
  8.         }

This method is initially called when my jobs window is created for the first time, and it works perfectly fine there. All of the jobs (the jobs are packages that need to be delivered) are created normally as children of the "Jobs Grid" for this particular window, which is in turn a child of the scroll view, which is a child of the window itself. Everything is great at this point.

However, the problem I am running into occurs after several jobs have been removed from the window and I want to create more jobs to replace them. I call the same method to accomplish this task, but this time the jobs are created and placed in the center of my game window, and they are being added to the hierarchy as children of UI Root, instead of as children of the "Jobs Grid" for the window. I can drag them into the jobs window, which then reparents them to the "Jobs Grid", but I am unsure why AddChild() is not doing this for me when they are instantiated..

I should probably also mention that the script containing this method is attached to the job window itself. Any insight into where I am going wrong would be greatly appreciated.

John.Bergman

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 30
    • View Profile
Re: AddChild() not instantiating correctly in the hierarchy
« Reply #1 on: December 31, 2013, 02:55:01 PM »
This is similar to the issue I was having earlier that have not been able to reproduce.

As part of that reading, it was mentioned that UIGrid.Reposition() should be called; I wonder if that would help with the problem you are having?

TimL

  • Guest
Re: AddChild() not instantiating correctly in the hierarchy
« Reply #2 on: December 31, 2013, 03:02:42 PM »
Thank you for the tip. I will see if I can look into UIGrid.Reposition() to see if that will help me out here.

TimL

  • Guest
Re: AddChild() not instantiating correctly in the hierarchy
« Reply #3 on: December 31, 2013, 04:45:49 PM »
Well, I was able to solve part of the problem. It seems that my line assignment line for the variable "grid" was working correctly the first time it ran, but any subsequent time it was resetting the value of grid back to null. I moved that line to Start() so it only runs once and now the new jobs appear in the window but they are still stacking on top of each other instead of each new job appearing on a new line in the grid.

I tried using UIGrid.Reposition() (both before and after the loop to create the jobs) to adjust the positioning of the jobs in the grid, but it had no effect. However, selecting Execute in the Inspector with the grid selected does reposition the jobs in the window so they are displayed correctly. Also, dragging a job out of the window makes all the jobs still in the window adjust to be displayed properly. My understanding was that Reposition() performed the same task as selecting Execute in the inspector.

I am just a little puzzled that my code works fine the first time it runs, then every time after that the jobs just get stacked instead of being properly spread out in the grid.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: AddChild() not instantiating correctly in the hierarchy
« Reply #4 on: January 01, 2014, 10:34:08 PM »
Reposition() won't work unless UIGrid's Start() function has been executed. I believe I already addressed this in the last f3 upload.

TimL

  • Guest
Re: AddChild() not instantiating correctly in the hierarchy
« Reply #5 on: January 02, 2014, 09:48:49 AM »
Thank you for the response, Aren. I had been a little hesitant to update in the middle of the project I am working on, but the update appears to have worked flawlessly. BIG thanks for making the update process happen so smoothly.

Unfortunately updating to 3.0.8 f3 does not appear to have corrected the problem I am having. I have included a few screenshots to illustrate what is happening. In 1, you can see how the window appears when it is first opened, which is also when the window itself is instantiated. In 2, you can see that all of the jobs have been taken out of the window (they were not destroyed, just moved to another window). In 3, I have closed the window and reopened it (the window was deactivated, then reactivated), which triggers the creation of new jobs. In 4, I started to drag one of the jobs off of the stack, then let it snap back after the grid reorganized itself.

One thing that I have noticed is that when I am looking at the UIGrid script in the editor without the game playing, it has the checkmark indicating that it is active. However, when the game is running, the UIGrid script no longer has the checkmark to indicate it is active, and I cannot toggle it on. I am not sure if this is supposed to happen, or if I am doing something to deactivate the script, or if it is just one of Unity's odd little quirks. Of course, it may be completely unrelated to the problem I am experiencing.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: AddChild() not instantiating correctly in the hierarchy
« Reply #6 on: January 02, 2014, 11:16:05 AM »
The grid disables itself after executing its repositioning logic, which is why you see it disable itself at run-time.

So what are you calling in your code (calling Reposition() after adding your items?) Reading your previous replies you mention resetting some grid value to null... which grid value is that?

TimL

  • Guest
Re: AddChild() not instantiating correctly in the hierarchy
« Reply #7 on: January 02, 2014, 12:08:04 PM »
I apologize for not being clear when I mentioned grid was being set to null. My script has a variable named "grid" that stores a reference to the GameObject containing the grid for the window where the jobs are stored, and the script is attached to the window itself. The hierarchy looks like this:

+ Jobs Window (script is attached here)
- + Jobs Scroll View
- - + Jobs Grid
- - - + Package Prefab
- - - + Package Prefab
- - - + etc...

Initially, I was setting the reference to the grid GameObject every time I called the method that I included in my initial post (the line grid = GameObject.Find("Jobs Grid");). What I noticed when looking in the inspector, is that this would properly set the value the first time the method was called when the window was first instantiated (image 1). However, any time the method was called after the first time, the value of grid would always be set to null (image 2).

Of course, that caused problems when I included the Reposition() call, so I moved the assignment line for grid into the Start() method, and that got rid of the problem with the value for that variable being reset (in addition to certainly being better for performance since I am only using Find once). Unfortunately it did not help me to get the new objects that are being created after the first time the method is called to stop stacking on top of each other. With the edits that I have made since my original post, this is what I currently have:

  1.         // CreateJobs() is called to populate the job window.
  2.         private void CreateJobs(int numJobs) {
  3.                 for (int i = 0; i < numJobs; i++) {     // Repeat until numJobs has been reached...
  4.                         NGUITools.AddChild(grid, UIPackagePrefab);      // Create a package object and add it to the scene as a child of grid.
  5.                 }
  6.  
  7.                 grid.GetComponent<UIGrid>().Reposition();       // Adjust grid to properly display items that it contains.
  8.         }

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: AddChild() not instantiating correctly in the hierarchy
« Reply #8 on: January 03, 2014, 04:49:57 AM »
Never use GameObject.Find. That function is a blight of Unity and should be killed with prejudice. Make a public variable instead, then drag & drop the value in inspector.

Furthermore, I suggest you reference the UIGrid directly instead of its game object.

Doing your instantiation in Start() is the right place. Make sure that UIGrid's Reposition() function has this check up top:
  1.                 if (Application.isPlaying && !mInitDone && NGUITools.GetActive(this))
  2.                 {
  3.                         mReposition = true;
  4.                         return;
  5.                 }
Before it used to be:
  1.                 if (Application.isPlaying && !mStarted)
  2.                 {
  3.                         mReposition = true;
  4.                         return;
  5.                 }
...which is why it would not execute until after the script executed its Start() function, which would not happen if the script was disabled.

TimL

  • Guest
Re: AddChild() not instantiating correctly in the hierarchy
« Reply #9 on: January 03, 2014, 09:29:44 AM »
I feel a little bit foolish right now. I know GameObject.Find is a really bad option to use. I had used it in this case because I knew the object I wanted to reference was being instantiated at run time and thought I could not create a direct link to it using the inspector. I just realized that since the script and UIGrid object are both in the same prefab, I can go ahead and create that direct link without worrying about the script grabbing the wrong UIGrid object. :-[

I checked the Reposition() function in the UIGrid script that I currently have installed, and it does have the newer check at the top of it. I also changed my grid variable to reference the UIGrid script directly instead of the GameObject the UIGrid script is attached to.

I should probably clarify that the initial problem of the package objects not being instantiated correctly in the hierarchy has been resolved by moving the assignment for the grid variable to Start() (and now by performing that assignment in the inspector). The problem I am experiencing now is that the package objects that are instantiated in the grid after the grid is initially instantiated for the first time are all stacking on top of each other instead of being properly spread out in the grid.

Aren, I really do appreciate any and all help you can provide to assist me in figuring out what I am doing wrong, but this is not currently critically important for me. I am finishing up a prototype, so I don't need everything to look perfect as long as it works (which it does so far). I know you are busy, so don't worry about putting too much time into helping me with this issue. I don't need to worry about actually resolving this until I get the go-ahead to complete the game.

This product is awesome, by the way.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: AddChild() not instantiating correctly in the hierarchy
« Reply #10 on: January 03, 2014, 10:08:21 AM »
You mentioned you're calling UIGrid's Reposition() function after adding the children, correct? Can you add some Debug.Logs in that function to see how far it gets before exiting? There is no reason why Reposition() function shouldn't reposition all the children now.

TimL

  • Guest
Re: AddChild() not instantiating correctly in the hierarchy
« Reply #11 on: January 03, 2014, 10:12:53 AM »
Add debug logs inside the Reposition() function? I was actually thinking about doing that later today, if I have some time. I have a couple more features I need to implement today, then get my code comments caught up.