Author Topic: SpringPanel.onFinished sometimes very late  (Read 4989 times)

Gregzo

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 64
    • View Profile
SpringPanel.onFinished sometimes very late
« on: August 02, 2013, 02:20:08 AM »
Hi,

I'm having a rare issue where SpringPanel's onFinished delegate does not fire immediately when UICenterOnChild has finished centering, sometimes by as much as 10 seconds.
It doesn't happen often, I have to test for some times as much as 10 minutes for the bug to show up, but it's very much there.

Then again, it might be me : I'm using a modified version of UICenterOnChild.

Any help appreciated!

UICenterOnChildManual.cs :

  1. public class UICenterOnChildManual : MonoBehaviour
  2. {
  3.         UIDraggablePanel mDrag;
  4.         GameObject mCenteredObject;
  5.        
  6.         public SpringPanel.OnFinished onFinished;
  7.        
  8.         void Awake ()
  9.         {
  10.                 mDrag = gameObject.GetComponent ( typeof ( UIDraggablePanel ) ) as UIDraggablePanel;
  11.                 //Test
  12.                 onFinished += Test; // for debugging purposes
  13.         }
  14.        
  15.         /// <summary>
  16.         /// Recenter the draggable panel on targetTrans.
  17.         /// </summary>
  18.  
  19.         public void CenterOnChild( Transform targetTrans )
  20.         {
  21.                 Debug.Log ("CenterOnChild called at "+Time.time);
  22.                
  23.                 if (mDrag.panel == null) return;
  24.                 // Calculate the panel's center in world coordinates
  25.                 Vector4 clip = mDrag.panel.clipRange;
  26.                 Transform dt = mDrag.panel.cachedTransform;
  27.                 Vector3 center = dt.localPosition;
  28.                 center.x += clip.x;
  29.                 center.y += clip.y;
  30.                 center = dt.parent.TransformPoint(center);
  31.  
  32.                 // Offset this value by the momentum
  33.                 mDrag.currentMomentum = Vector3.zero;
  34.  
  35.                 // Figure out the difference between the chosen child and the panel's center in local coordinates
  36.                 Vector3 cp = dt.InverseTransformPoint(targetTrans.position);
  37.                 Vector3 cc = dt.InverseTransformPoint(center);
  38.                 Vector3 offset = cp - cc;
  39.  
  40.                 // Offset shouldn't occur if blocked by a zeroed-out scale
  41.                 if (mDrag.scale.x == 0f) offset.x = 0f;
  42.                 if (mDrag.scale.y == 0f) offset.y = 0f;
  43.                 if (mDrag.scale.z == 0f) offset.z = 0f;
  44.  
  45.                 // Spring the panel to this calculated position
  46.                 SpringPanel.Begin(mDrag.gameObject, dt.localPosition - offset, 8f).onFinished = onFinished;
  47.         }
  48.        
  49.         void Test ()
  50.         {
  51.                 Debug.Log ("SpringPanel finished at "+Time.time);
  52.         }
  53. }

MGB

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 15
    • View Profile
Re: SpringPanel.onFinished sometimes very late
« Reply #1 on: August 08, 2013, 06:14:01 AM »
I've had this happen too... seems to be worse on faster machines.
Possibly some problem in SpringLerp integration..?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: SpringPanel.onFinished sometimes very late
« Reply #2 on: August 08, 2013, 09:12:50 AM »
Might be related to the distance being too small. Look inside SpringPanel:
  1. if (mThreshold >= Vector3.Magnitude(after - target))
where mThreshold is set as:
  1. mThreshold = (target - mTrans.localPosition).magnitude * 0.005f;
In SpringPanel.Begin it only resets the threshold if the component is disabled, so perhaps move out the
  1. sp.mThreshold = 0f;
outside that "if" statement?
You can also try changing the "if (mThreshold == 0f)" part in Update to the following:
  1. if (mThreshold == 0f)
  2. {
  3.         mThreshold = (target - mTrans.localPosition).magnitude * 0.005f;
  4.         mThreshold = Mathf.Max(mThreshold, 0.00001f);
  5. }

Gregzo

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 64
    • View Profile
Re: SpringPanel.onFinished sometimes very late
« Reply #3 on: August 09, 2013, 12:32:17 AM »
Hi Aren,

Thanks for the tips. So far, I've designed around it ( did my own, stripped version of SpringPanel, optimized for use in my pickers. NGUI credited, of course... ).

As the bug arises in a commercial asset, can't tweak NGUI classes.

Will there still be NGUI updates, or are you racing towards the Graal of GUIs, crunching away?

Cheers,

Gregzo

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: SpringPanel.onFinished sometimes very late
« Reply #4 on: August 09, 2013, 04:22:24 PM »
If the fixes I posted resolve the issue, then they will be promoted to the live version's repository -- but someone has to test them first ;)

NGUI isn't going anywhere. While I am indeed focusing on the upcoming GUI atm, I will still be updating NGUI.

Gregzo

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 64
    • View Profile
Re: SpringPanel.onFinished sometimes very late
« Reply #5 on: August 11, 2013, 05:14:28 AM »
Thanks for the reply Aren.

Unfortunately, I'm getting the bug so rarely that it is very hard to test properly. A user of NGUI Infinite Pickers reported it happened 100% of the time on his machine, and sent me the following patch that worked for him :

  1. if (mThreshold >= Vector3.Magnitude(after - target) || Vector3.Magnitude(after - target) < 0.001f)

It might not be the best solution, but wth the bug occurring so rarely on my machine, it's very hard to know reliably what works and what doesn't.

Cheers,

Gregzo