Author Topic: UIDraggablePanel: Help with overshoot  (Read 11912 times)

Rafe

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 78
    • View Profile
UIDraggablePanel: Help with overshoot
« on: August 21, 2012, 12:53:13 AM »
Hi,

I'm hoping you can offer some advice. I think followed the example scene to setup a draggable/scrolling panel correctly. It mostly works. I have...
  1. UIDraggablePanel
  2. -- Grid
  3. -- -- UI Drag Panel Contents
  4. -- -- UI Drag Panel Contents
  5.  

Issues I need to solve:
  • The panel doesn't snap when released. The spring is too weak and drifts off rather than snaps. I tried to change the target of the spring panel to 0, and up the strength, but the panel takes over control and sets it to a value that is off zero. How can I get a crisp snap?
  • How do I reset the scroll back to its start position of 0? Should I just set the transform? I tried ResetPosition() but it threw an error

I need to learn how to do this quickly because the next widget I have to convert to nGUI is a programatically driven queue of icons that I need to pop, insert and scroll via script.

I did some searching and checked the examples, but I feel like I am missing something.


Cheers,

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #1 on: August 21, 2012, 01:07:31 PM »
"drifts off" suggests that its not working at all. Where is your script attached that does the snapping?

Rafe

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 78
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #2 on: August 22, 2012, 01:17:52 AM »
"Drifts off" doesn't paint the right picture. I mean it doesn't do a hard snip, it stops off-"center".

A. The SpingPanel (added at runtime, or added by me, same result) changes from (0, 0, 0) to (0, 19.00002, 0).
B. When I drag half way between the two items and let go, the spring doesn't activate at all
C. I can drag past the panels in both directions, I need it to stop when it hits the edge of a panel.

What is changing the spring value and why is it off-center?

I don't know what you mean by "script that does the snapping". I am only using a Draggable Panel set to MomentumAndSpring. It adds a Spring Panel at runtime as soon as I drag and let go. It is on the same GameObject as a UIPanel in the hierarchy I posted above.



[Edit:] I have two UIDragPanelContents in this grid. The first springs to the odd value I described. The second springs to the right value. They should be snaped at 0 and -150 in Y and I'm getting 19 and -150.

+ I need the panel to snap to the nearest no matter where the player lets go.

Also, can you comment on my second bullet point in my original post?:
Quote
"How do I reset the scroll back to its start position of 0? Should I just set the transform? I tried ResetPosition() but it threw an error"

« Last Edit: August 22, 2012, 01:23:15 AM by Rafe »

Rafe

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 78
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #3 on: August 24, 2012, 10:01:46 PM »
I'm just replying to bump this. I know you have a lot of posts to get through and this one is quite involved. Perhaps it could be tutorialized since it is a common need. Anyway, please see my last post above.

Cheers,

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #4 on: August 25, 2012, 01:08:49 AM »
Sorry, yup -- looks like I missed your reply.

Why is UIDraggablePanel.ResetPosition giving you an error? It's supposed to do just that -- reset everything to the beginning, where beginning is defined by relativePositionOnReset.

Btw, when you say that "the panel doesn't snap" when you release the mouse button -- why would it snap? It will only snap if you've released the mouse outside of the bounds with "restrictWithinPanel" set, or you set up with UICenterOnChild, like in the scroll view example.

Rafe

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 78
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #5 on: August 25, 2012, 01:20:53 PM »
I'll look in to the UICenterOnChild. It is very important that the scrolling content always snaps to the nearest center. Perhaps this will fix the other issue I am seeing too, but the default behavior feels random so I am trying to understand it...

A. The SpingPanel (added at runtime, or added by me, same result) changes from (0, 0, 0) to (0, 19.00002, 0).

This happens when it is activated by the draggable panel (I assume). If I set it back to 0, then drag and let go, it resets to 19.

If I set the draggable panel to not spring anymore, and do it manually, the number doesn't change.

...why?

Rafe

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 78
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #6 on: August 25, 2012, 02:53:40 PM »
OK, I added the center on children component to the grid (code comments say "container" by the way) and it seems to work. It would be cool to have an option for bounding box too. My items are all positioned based on the bottom right corner. I'm sure once I add parent transforms that are centered it will work.

I'm not sure how I would have figured this out if it wasn't for your last post. I missed it in the example.

Thanks!
« Last Edit: August 25, 2012, 02:58:37 PM by Rafe »

Rafe

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 78
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #7 on: August 25, 2012, 03:22:15 PM »
Regarding the ResetPosition() error. It is a NullReferenceException at line 331 of NGUIMath.cs:
  1.                 UIWidget[] widgets = child.GetComponentsInChildren<UIWidget>() as UIWidget[];
  2.  

I put in a log message and child IS null here. Regardless of the reason, it would be cool to protect against this. I'll look a bit more and edit this post if I can find anything new.

'child' comes from line 135 in UIDraggablePanel.cs: mTrans which is set in awake. I'm still trying to figure out how it ends up null:
  1.                                 mBounds = NGUIMath.CalculateRelativeWidgetBounds(mTrans, mTrans);
  2.  

Expanded TraceBack:
  1. NullReferenceException
  2. UnityEngine.Component.GetComponentsInChildren[UIWidget] (Boolean includeInactive) (at C:/BuildAgent/work/d9c061b1c154f5ae/Runtime/ExportGenerated/Editor/UnityEngineComponent.cs:146)
  3. UnityEngine.Component.GetComponentsInChildren[UIWidget] () (at C:/BuildAgent/work/d9c061b1c154f5ae/Runtime/ExportGenerated/Editor/UnityEngineComponent.cs:149)
  4. NGUIMath.CalculateRelativeWidgetBounds (UnityEngine.Transform root, UnityEngine.Transform child) (at Assets/NGUI/Scripts/Internal/NGUIMath.cs:332)
  5. UIDraggablePanel.get_bounds () (at Assets/NGUI/Scripts/Interaction/UIDraggablePanel.cs:135)
  6. UIDraggablePanel.SetDragAmount (Single x, Single y, Boolean updateScrollbars) (at Assets/NGUI/Scripts/Interaction/UIDraggablePanel.cs:364)
  7. UIDraggablePanel.ResetPosition () (at Assets/NGUI/Scripts/Interaction/UIDraggablePanel.cs:417)
  8. <MyScript>.Refresh (.Unit target) (at Assets/Scripts/UI/<MyScript>.cs:323)

By the way, it would really help code readability if you put "this." before all instance fields and the name of the class before all static functions. That way it would be easy to tell what is just a function-scope variable and waht is an instance or static field.

OK ------------------------------------------------

It looks like this is a race-situation. I am starting the level with this panel hidden, so I guess Awake() hasn't run for this panel when I call ResetPosition(). I added a check for this in UIDraggablePanel.bounds:
  1.         public Bounds bounds
  2.         {
  3.                 get
  4.                 {
  5.                         if (!mCalculatedBounds)
  6.                         {
  7.                                 mCalculatedBounds = true;
  8.                 if (this.mTrans == null)
  9.                     this.mTrans = this.transform;
  10.  
  11.                                 mBounds = NGUIMath.CalculateRelativeWidgetBounds(mTrans, mTrans);
  12.                         }
  13.                         return mBounds;
  14.                 }
  15.         }
« Last Edit: August 25, 2012, 04:49:14 PM by Rafe »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #8 on: August 25, 2012, 04:10:46 PM »
If you use the script before its Awake gets called, then yeah you will have problems. Better figure out why that's happening and fix it -- for example moving your logic out of Awake and into Start, so that it's guaranteed to be called after all scripts wake up.

Rafe

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 78
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #9 on: August 25, 2012, 04:48:30 PM »
First, the fixes I made to your code work. They fix the race issue and you have all the information you need to implement it I think. I can now call ResetPostion() as part of my init code (which makes a lot of sense in my particular usage case... I am setting up the GUI before I show it all in one function). Fixed.

"Better figure out why that's happening and fix it "

With all due respect. It is your API, you should protect against init races. It is frustrating when I run someone else's code and there is an unhandled exception. I paid for the full license, so I expect to be able to lean on the developer. I thought you would appreciate knowing you missed an unexpected null reference exception. I know how rare it is to get users that report tracebacks and possible fixes. A 'thank you' can go a long way. I'm sorry if this sounds harsh but I'm a bit frustrated on this Saturday afternoon. As a new user it is hard to ask the right questions sometimes.

So.... Lets start over.

I have a snapping scroll list now. Awesome! (not sarcastic at all, I'm happy.)


My big questions now are, from a script...

1) ...how do I scroll to the last item?

2) ...how do I insert/remove items?


These are the last two things I need to figure out to get our GUI fully moved over to nGUI.
« Last Edit: August 25, 2012, 04:51:02 PM by Rafe »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #10 on: August 25, 2012, 04:55:49 PM »
Sorry, I just meant to suggest that if you have a race condition happening, the safest thing to do is to eliminate the cause rather than hide the symptom. The null check should be there, you're right, but the problem causing it still happens whether it's there or not, and may cause other issues down the line so it's safer to fix it at the source.

Scrolling to the end can be done using SpringPanel.Begin(targetPosition), the same way CenterOnChild works (line 90).

Insert/remove items -- just add items to the table / grid via NGUITools.AddChild, then call the table / grid's reposition function.

abacus

  • Guest
Re: UIDraggablePanel: Help with overshoot
« Reply #11 on: March 06, 2013, 05:49:12 AM »
Rafe, just wanted to say thanks for the fix you posted. It solved my problem, too! (The one where you set mTrans in bounds if it is not already set)

DZP

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 17
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #12 on: December 18, 2013, 05:55:18 AM »
Also replying to say thanks for the fix. Can't believe this still exists.....

marsh

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1
    • View Profile
Re: UIDraggablePanel: Help with overshoot
« Reply #13 on: January 22, 2014, 10:02:11 AM »
Thanks for the fix!