Author Topic: Question on UI Center ON Child  (Read 9164 times)

blitzer

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 52
    • View Profile
Question on UI Center ON Child
« on: March 27, 2014, 04:53:50 PM »
I'm running into a problem with using UICenterOnChild, the script is causing the view to center on objects that are not in the center of the viewing area.

More details:
I've got 4 sprites in a grid (which is itself a child of a UIPanel with a UIScrollView attached) sorted and arranged from left to right, and sprites 1-3 take up the entire view-able space (with 1 on the left, 2 in the center, and 3 on the right). The sizing and arrangement of each element and the grid is handled by script in Awake(), and on its own works just fine. However, when trying to use UICenterOnChild, the script tries to focus the view seemingly half way between sprites 3 and 4, and then clicking on any sprite makes the view jump back to 2 (which is where it normally is without the script) after which everything works fine.

I've tried changing the UICenterOnChild script, enabling and disabling from different places in scripts, and a few other things but nothing changes this behavior. Does anyone know or have an idea as to what is going on?


--Update:
As a work around, I just turned the Spring Panel power down to 0 in Awake() and reset its value in Start (). Not really a solution but it prevents the problem from happening.
« Last Edit: March 27, 2014, 08:05:11 PM by blitzer »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Question on UI Center ON Child
« Reply #1 on: March 28, 2014, 12:52:03 AM »
Center on child centers on the child's position, not its center. So if you have a widget that uses top-left corner as its pivot point, the script will center on the top-left corner.

blitzer

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 52
    • View Profile
Re: Question on UI Center ON Child
« Reply #2 on: March 28, 2014, 02:54:49 AM »
@ArenMook, thank you for the reply - after more work I've found that something with the UIScrollView is causing the problem (seemingly something with Reset Clipping Position) that occurs on the first mouse click but never after that. I'll try making a video clip on it because its very hard to explain...
https://www.youtube.com/watch?v=vaxf-LNBpZQ&feature=youtu.be

Notice in the video, that the first time I click on of the sprites, the panel jumps a bit (and is then dragged back by CenterOnChild which is on the Grid object), but after this jump occurs, it will not happen again. See that when Reset Clipping Position is pressed, the same thing occurs.

I'm not sure what it means but if you (or anyone else) have an idea how to deal with it, I would really like to know (its been driving me crazy).

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Question on UI Center ON Child
« Reply #3 on: March 28, 2014, 10:19:05 AM »
Hard to tell what's going on in the beginning of the video as it remains blurry for the first 30%. If I was to guess though, I'd say this is related to where the content is instantiated. UICenterOnChild executes when it starts up, but if the content is instantiated at a later date it's up to you to call its Recenter() function.

blitzer

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 52
    • View Profile
Re: Question on UI Center ON Child
« Reply #4 on: March 28, 2014, 01:39:17 PM »
@ArenMook, all that is happening in the beginning is that the content is arranged during Awake(), and when the first click occurs on the content, it "jumps" a little to the right. At any rate, I gave your suggestion a try and made a method that calls Recenter() in Update(), unfortunately it does not correct the "jumping" behavior (it still happens 1 time, then never again). Do you have any idea how Reset Clipping Position might be involved? Since it causes the exact same "jump" during a running scene?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Question on UI Center ON Child
« Reply #5 on: March 29, 2014, 05:43:29 AM »
Awake() is not the right place for this. You should never touch anything in Awake() that lies outside the class you received the Awake() in. It's only for local variable initialization. Everything else should be in Start() instead. Check Unity's docs on this for more info.

blitzer

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 52
    • View Profile
Re: Question on UI Center ON Child
« Reply #6 on: March 29, 2014, 03:41:03 PM »
@ ArenMook, I appreciate the advice (and I have re-written the script to separate what should be in Awake from Start), unfortunately, I still get the same behavior...Maybe I could post the script if that would help?

blitzer

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 52
    • View Profile
Re: Question on UI Center ON Child
« Reply #7 on: March 29, 2014, 10:41:37 PM »
Update:
I re-wrote the way I was making adjustments to the grid, and seem to have traded 1 problem for another. Now, everything is aligned and there is no "jump", but now when I try to drag the objects in the scroll view, the view jitters back and forth (and the UIPanel center and offset change continuously) until the problem fixes itself eventually...:
https://www.youtube.com/watch?v=Krd5jHGKA_o&feature=youtu.be

I read this thread and noticed they also mention this jittering, I applied the fix for it but it has not resolved my issue:
http://www.tasharen.com/forum/index.php?topic=8355.0

I have had success with removing the anchor points from the GameObject that contains the UIPanel and UIScrollView and have not seen this issue occur. But I don't know why it works or what it means in the big picture. Is there a way to remove an anchor through script?
--On further testing, the scrollview is still jumping a bit, but its a very small jump.

Attached is the script I'm using as of now to adjust the grid size. Any insight is appreciated.
« Last Edit: March 30, 2014, 12:01:12 AM by blitzer »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Question on UI Center ON Child
« Reply #8 on: March 30, 2014, 07:27:37 AM »
Again you're with the Awake()...

As I mentioned... don't use it. You see how you're doing GameObject.Find? Awake() is called before parents / children are set in some cases. Even if it's not causing any issues for you in your particular code, it will bite you in the ass in the long run. Plus your code doesn't do anything between Awake() and Start(), there is zero reason to have that Awake() function.

Next... you're calling Panel.Update() for some reason at the beginning of Start(). What for? Update() needs to be called at a specific time -- after Start() has been called on the panel. There is no guarantee that that's the case here. Never call Start, Update, LateUpdate, etc functions of other scripts. This is plain wrong.

I'm guessing you're doing it because you need to have your panel's width known? If so, use UIRect's UpdateAnchors() function. Not Update().

blitzer

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 52
    • View Profile
Re: Question on UI Center ON Child
« Reply #9 on: March 30, 2014, 01:38:58 PM »
Thank you again for your insights, I will make the changes (and I'm sorry to keep needing your help (which I really do appreciate), its clear I'm trying to do more than my current experience allows for).

About Awake - I read the Unity docs on it, where is says that awake should be safe for assigning in-script variables and reference between scripts. But if parent/children relationships may not be established (is that for any object or NGUI objects?) is there really any reason to use Awake ever?

Anyway, thank you again, sorry be such a headache.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Question on UI Center ON Child
« Reply #10 on: March 30, 2014, 03:22:25 PM »
Awake() is only useful for local variable initialization, so no, you rarely need it.

tvhnet

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 7
    • View Profile
Re: Question on UI Center ON Child
« Reply #11 on: August 09, 2016, 04:13:18 AM »
Center on child centers on the child's position, not its center. So if you have a widget that uses top-left corner as its pivot point, the script will center on the top-left corner.

How to custom Recenter() to center on child's center no matter what its pivot is?
Thanks,

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Question on UI Center ON Child
« Reply #12 on: August 09, 2016, 06:25:43 AM »
Easiest solution is to simply position your widgets so that they are centered from the start.

Alternative approach is to create a custom version of UICenterOnChild that would use NGUIMath.CalculateRelativeWidgetBounds to determine the bounds of each child in its Recenter() function instead of simply using the transform's position. Note that this would be a lot more expensive.