Author Topic: [HOTFIX]Other Tween engines and NGUI  (Read 10428 times)

Genhain

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 38
    • View Profile
[HOTFIX]Other Tween engines and NGUI
« on: November 05, 2014, 11:09:58 PM »
Not that there is anything wrong With NGUI tweening method, but i wanted something with a few more options and intricacy, so i tried to give HOTweens successor DOTween a go. And it seemed to work, until anchors got involved.

if you tried tweening anything with DOTween that had an anchor...it would move, and then snap back to it's from. So i discovered that NGUI movement tweening does a little thing in the background which updates the anchors rect as you tween which caused me to come up with this.

  1. public static Tweener DOLocalMoveWidget (this Transform target, Vector3 endValue, float duration, DG.Tweening.Core.TweenCallback callback = null, bool snapping = false)
  2. {
  3.         return DOTween.To(()=>target.localPosition,x=> target.localPosition = x,endValue,duration).OnComplete(()=>{TweenPosition.Begin(target.gameObject,0,endValue).PlayForward();if(callback!= null)callback();});
  4. }
  5.  
  6. public static Tweener DOLocalMoveXWidget(this Transform target, float endValue, float duration, DG.Tweening.Core.TweenCallback callback = null, bool snapping = false)
  7. {
  8.         return target.DOLocalMoveX(endValue,duration,snapping).OnComplete(()=>{TweenPosition.Begin(target.gameObject,0,new Vector3(endValue,target.localPosition.y)).PlayForward();if(callback!= null)callback();});
  9. }
  10.  
  11. public static Tweener DOLocalMoveYWidget(this Transform target, float endValue, float duration, DG.Tweening.Core.TweenCallback callback = null, bool snapping = false)
  12. {
  13.         return target.DOLocalMoveY(endValue,duration,snapping).OnComplete(()=>{TweenPosition.Begin(target.gameObject,0,new Vector3(target.localPosition.x,endValue)).PlayForward();if(callback!= null)callback();});
  14. }
  15.  
  16. public static Tweener DOLocalMoveZWidget(this Transform target, float endValue, float duration, DG.Tweening.Core.TweenCallback callback = null, bool snapping = false)
  17. {
  18.         return target.DOLocalMoveZ(endValue,duration,snapping).OnComplete(()=>{TweenPosition.Begin(target.gameObject,0,new Vector3(target.localPosition.x,target.localPosition.y,endValue)).PlayForward();if(callback!= null)callback();});
  19. }
  20.  

And it all seems to work, with now what seems to be one small exception if after deactivating the view these tweens were in and returning to it, the DOTweens now no longer show any visible sign of interpolation..but after their duration is up the oncomplete is called and they snap to their target "to" which indicates that the onComplete is being called and NGUI UITweens are being called...So my question is is there something that UITween does that is causing this? or does anyone have any suggestions about the code above to fix this?

I will keep experimenting and update with progress or discoveries as to the exact cause of the issue if i can.
« Last Edit: November 13, 2014, 02:33:32 AM by Genhain »

Genhain

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 38
    • View Profile
Re: Other Tween engines and NGUI
« Reply #1 on: November 05, 2014, 11:38:31 PM »
UPDATE

So i came up with this little ditty

  1. Sequence mySequence = DOTween.Sequence();
  2.  
  3. mySequence
  4.                 .Append(testTween.DOLocalAxisRotate(new Vector3(0,0,90),1))
  5.                 .Append(testTween.DOLocalMoveWidget(new Vector3(30,30,0),1))
  6.                 .Append(testTween.DOLocalMoveXWidget(60,1))
  7.                 .Append(testTween.DOLocalMoveYWidget(60,1))
  8.                 .Append(testTween.DOLocalMoveWidget(new Vector3(0,0,0),1))
  9.                 .Append(testTween.DOLocalRotate(new Vector3(0,0,180),1))
  10.                 .Append(testTween.DOPunchScale(new Vector3(2,2,1),1))
  11.                 .Append(testTween.DORotate(new Vector3(0,0,-180),1))
  12.                 .Append(testTween.DOScale(new Vector3(1.5f,1.5f,1),1))
  13.                 .Append(testTween.DOLocalMoveWidget(new Vector3(0,-50,0),1))
  14.                 .AppendCallback(()=>{NGUITools.SetActive(testTween.gameObject,false);})
  15.                 .AppendInterval(1)
  16.                 .AppendCallback(()=>{NGUITools.SetActive(testTween.gameObject,true);});
  17.  

and it essentially plays through once fine...And then once it hits mySequence.Restart(); after deactivating and reactivating them is when the movement tweens stop interpolating. without setting them inactive and active again it works fine, and again this is only if anchors are present and seems to only affect positional Tweens...the rotates and scale ones do not seem affected at all.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Other Tween engines and NGUI
« Reply #2 on: November 06, 2014, 02:13:52 AM »
I have to say your code is utterly unreadable. There is not much I can do to help you with some third party tween system in any case.

Genhain

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 38
    • View Profile
Re: Other Tween engines and NGUI
« Reply #3 on: November 06, 2014, 03:41:46 AM »
I have to say your code is utterly unreadable. There is not much I can do to help you with some third party tween system in any case.

well i am using lambda statements so it can get a little cluttered. i'll expand one out

  1. public static Tweener DOLocalMoveXWidget(this Transform target, float endValue, float duration, DG.Tweening.Core.TweenCallback callback = null, bool snapping = false)
  2. {
  3.     return target.DOLocalMoveX(endValue,duration,snapping)
  4.      .OnComplete(()=>
  5.     {
  6.         TweenPosition.Begin(target.gameObject,0,new Vector3(endValue,target.localPosition.y)).PlayForward();
  7.         if(callback!= null)callback();
  8.     });
  9. }
  10.  

Hopefully that is more readable.

Essentially i am using the tween engine to move something visually and then in the onComplete lambda call TweenPosition at a duration of 0 seconds to make it happen instantly which will account for the anchors and such

I'm not expecting you to know how a third party system will work, but as i have said i have been ruling out what the causes are and as stated it's the activation of anchors that is causing the symptom i describe and looking at your code during your position tweens you use "NGUIMath.MoveRect(mRect, value.x, value.y);" to accommodate the anchors i was just enquiring as if you possibly have any insight as to why anchors along with deactivating and activating an object would cause it to be unable to interpolate any longer since you developed them and probably ran into one or two gotcha moments that would help explain the behaviour i am experiencing?

Genhain

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 38
    • View Profile
Re: Other Tween engines and NGUI
« Reply #4 on: November 06, 2014, 06:03:32 AM »
Okay is there a way for me to perhaps clear the anchors for the duration of the tween, keeping references of them...then once finished, put them back in and update them? i have managed to get as far as clearing the anchors...but trying to add them back in is proving difficult.

so somthing like
  1. UIWidget previousWidget = target.GetComponent<UIWidget>();
  2. //start tween
  3. UIRect.AnchorPoint oldLeftAnchor = previousWidget.leftAnchor;
  4. UIRect.AnchorPoint oldRightAnchor = previousWidget.rightAnchor;
  5. UIRect.AnchorPoint oldBottomAnchor = previousWidget.bottomAnchor;
  6. UIRect.AnchorPoint oldTopAnchor = previousWidget.topAnchor;
  7.  
  8. previousWidget.ClearAnchors();
  9.  
  10. //On tween finished
  11. previousWidget.leftAnchor = oldLeftAnchor;
  12. previousWidget.rightAnchor = oldRightAnchor;
  13. previousWidget.bottomAnchor = oldBottomAnchor;
  14. previousWidget.topAnchor = oldTopAnchor;
  15.  
  16. previousWidget.ResetAndUpdateAnchors();
  17.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Other Tween engines and NGUI
« Reply #5 on: November 07, 2014, 01:37:25 PM »
You shouldn't be changing anchor references. You should be working with them instead.

previousWidget.leftAnchor.Set(...);

Genhain

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 38
    • View Profile
Re: Other Tween engines and NGUI
« Reply #6 on: November 11, 2014, 01:37:49 AM »
Despite some experimentation i can not get it to work, i have opted to stop using the DOTween Tweening system in the mean time as i do not have time to get it working over other milestones. If i however come across any revelations i will post them here.

Genhain

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 38
    • View Profile
Re: [HOTFIX]Other Tween engines and NGUI
« Reply #7 on: November 13, 2014, 02:45:05 AM »
So i stumbled upon this by pure accident but i found a way for other tween engines(DOTween at least) and NGUI's anchoring system to coexist peacefully.

if you set the anchor update to OnEnable...there seems to be no more issues...I can't say why i am just ecstatic it seems to have solved me of the issue, but i would only call this a hotfix as i do not know if it might cause undue behaviours elsewhere.

anyway i will post the code for others to use if you are interested. Apologies if it is a tad utterly unreadable. But essentially DOLocalMoveWidget checks to see if it has a UIRect which any visual component with NGUI does, stores the previous updateFlag and sets it to onEnable and onCompleting sets it back to it's previous value.

  1. public static Tweener DOLocalMoveWidget (this Transform target, Vector3 endValue, float duration, DG.Tweening.Core.TweenCallback callback = null, bool snapping = false)
  2. {
  3.     UIRect rect = target.GetComponent<UIRect>();
  4.     UIRect.AnchorUpdate defaultUpdateFlag = UIRect.AnchorUpdate.OnUpdate;
  5.  
  6.     if(rect != null)
  7.     {
  8.         defaultUpdateFlag = rect.updateAnchors;
  9.         rect.updateAnchors = UIRect.AnchorUpdate.OnEnable;
  10.     }
  11.  
  12.     return DOTween.To(()=>target.localPosition,x=> target.localPosition = x,endValue,duration)
  13.         .OnComplete(()=>
  14.        {
  15.            TweenPosition.Begin(target.gameObject,0,endValue).PlayForward();
  16.            rect.updateAnchors = defaultUpdateFlag;
  17.            if(callback!= null)callback();
  18.        });
  19. }
  20.  
  21. public static Tweener DOLocalMoveXWidget(this Transform target, float endValue, float duration, DG.Tweening.Core.TweenCallback callback = null, bool snapping = false)
  22. {
  23.     Vector3 endPosition = target.localPosition;
  24.     endPosition.x = endValue;
  25.  
  26.     return target.DOLocalMoveWidget(endPosition,duration,callback,snapping);
  27. }
  28.  
  29. public static Tweener DOLocalMoveYWidget(this Transform target, float endValue, float duration, DG.Tweening.Core.TweenCallback callback = null, bool snapping = false)
  30. {
  31.     Vector3 endPosition = target.localPosition;
  32.     endPosition.y = endValue;
  33.  
  34.     return target.DOLocalMoveWidget(endPosition,duration,callback,snapping);
  35. }
  36.  
  37. public static Tweener DOLocalMoveZWidget(this Transform target, float endValue, float duration, DG.Tweening.Core.TweenCallback callback = null, bool snapping = false)
  38. {
  39.     Vector3 endPosition = target.localPosition;
  40.     endPosition.z = endValue;
  41.  
  42.     return target.DOLocalMoveWidget(endPosition,duration,callback,snapping);
  43. }
  44.