Author Topic: UITweener.ResetToBeginning() / UITweener.current issue  (Read 15370 times)

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
UITweener.ResetToBeginning() / UITweener.current issue
« on: May 08, 2014, 03:30:19 AM »
1. ResetToBeginning() issue:
if a tween is played when direction changed, i have call ResetToBeginning() and Play this way
  1. t.PlayReverse();
  2. t.ResetToBeginning();
  3. t.PlayReverse();
  4.  
because the ResetToBeginning wil stop the tween, and i have to set the direction first.

2. UITweener.current issue:
if a tween(new) is played when another tweener's(old) onFinished, and the new tween's duration is 0 ( or reset ),
the new tween's onFinished will not be called because UITweener.current is not null.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #1 on: May 09, 2014, 04:55:36 AM »
#2 first. Why do you have a tween with OnFinished that has a duration of 0? Why not just call the OnFinished stuff from the previous tween instead? Duration of 0 is questionable at best, and chaining notifications makes it possible to run into an issue where you have one tween's OnFinished immediately call another, which will immediatelly call the first again, etc... the null check is there to prevent such issues. It's not ideal, but I'd rather have that than the alternative.

#1 I am not quite clear on. Why do you need to do that? If a tween is played when direction changed? Not sure what you mean by that.

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #2 on: May 09, 2014, 06:57:39 PM »
in fact, #2 is happened because #1, i found the problem, so reported it.

#1:
in my case, there is a tween to tween a sprite's width, i use the it to show/hide loading screen,
and the tween.forward is hide, reverse is show.

the tween is disabled in the inspector, until i call LoadingScreen.Show().
then it just happened, it should play Reverse, and play forward when onFinished.

not work:
  1. // LoadingScreen.Show().
  2. private void Show()
  3. {
  4.    _tween.ResetToBeginning();
  5.    _tween.PlayReverse();
  6. }
  7.  
the first time, ResetToBeginning() will set the mFactor to 0.
PlayReverse() will make it play and finish immediately,
becaust mFactor += amountPerDelta * delta will less the 0.

AND, because of #2, so the onFinished will never be called, so my loading screen is hanging there.

it will be fixed:
  1. // LoadingScreen.Show().
  2. private void Show()
  3. {
  4.    _tween.PlayReverse();
  5.    _tween.ResetToBeginning();
  6.    _tween.PlayReverse();
  7. }
  8.  
Because the ResetToBeginning() will set the mFector to 1 correctly in my case.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #3 on: May 09, 2014, 11:33:06 PM »
ResetToBeginning() resets the play factor to 0 if you are playing it forward, and to 1 if you are playing it in reverse. So in your case in the 2nd function you play it in reverse, reset it to beginning (which sets the factor to 1), then play it in reverse again... it's odd. It's completely unnecessary to call PlayReverse() the second time. Keep in mind you can also adjust the tweenFactor yourself setting it to whatever you want. if you know you want it to start from 100% (the end), then do just that -- tween.tweenFactor = 1f;

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #4 on: May 12, 2014, 01:56:35 AM »
Because the amountPerDelta will be set to -3.33333 ( duration = 0.3 for instance ),
and the mFactor will be -3.33333 after mFactor += amountPerDelta * delta(if delta=1); because the mFactor = 0f as init value,
so after the first t.PlayReverse() is called, enabled is set false and the script stop.

« Last Edit: May 12, 2014, 10:24:45 AM by gyd »

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #5 on: May 14, 2014, 07:44:04 AM »
is this a BUG?
i think it should check the direction when played for first time.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #6 on: May 14, 2014, 11:03:27 PM »
ResetToBeginning() sets 'mFactor' to '1' when you call it after using PlayReverse():
  1.         public void ResetToBeginning ()
  2.         {
  3.                 mStarted = false;
  4.                 mFactor = (mAmountPerDelta < 0f) ? 1f : 0f;
  5.                 Sample(mFactor, false);
  6.         }
PlayReverse will set the amountPerDelta to a negative value. ResetToBeginning checks the value -- since it's below zero, mFactor will be 1.

So my question is... what version of NGUI are you using?

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #7 on: May 15, 2014, 03:15:31 AM »
ResetToBeginning() resets the play factor to 0 if you are playing it forward, and to 1 if you are playing it in reverse. So in your case in the 2nd function you play it in reverse, reset it to beginning (which sets the factor to 1), then play it in reverse again... it's odd. It's completely unnecessary to call PlayReverse() the second time. Keep in mind you can also adjust the tweenFactor yourself setting it to whatever you want. if you know you want it to start from 100% (the end), then do just that -- tween.tweenFactor = 1f;

i was replying this, about
"... then play it in reverse again... it's odd. It's completely unnecessary to call PlayReverse() the second time ..."

because the factor = 0 as init value, so the first PlayReverse() will be stopped right away, then reset to ResetToBeginning() set factor to 1f, that's why i need to call PlayReverse() one more time!

but if I call ResetToBeginning() before PlayReverse(), it will set the factor with wrong direction, i think the 2 functions are working with the conflict condition.

  1. bool mPlayFirstTime = true;
  2.  
  3. public void Play (bool forward)
  4. {
  5.         mAmountPerDelta = Mathf.Abs(amountPerDelta);
  6.         if (!forward) mAmountPerDelta = -mAmountPerDelta;
  7.  
  8.         // fix --
  9.         if( mPlayFirstTime )
  10.         {
  11.                 mPlayFirstTime = false;
  12.                 ResetToBeginning ();
  13.         }
  14.         // -- fix
  15.         enabled = true;
  16.         Update();
  17. }
  18.  

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #8 on: May 22, 2014, 09:05:06 PM »
please read the reply, i would like know the condition of the UITweener issues, thanks.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #9 on: May 23, 2014, 03:42:59 PM »
Factor is never 0. Look at the function I posted. If you played it in reverse before, amount per delta will be negative, so factor will be set to 1 by ResetToBeginning(), not 0. That function depends on what the "beginning" was. If you played it forward, 'beginning' is factor 0 after. If you played it in reverse, beginning is 1.

I also asked what version of NGUI do you have?

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #10 on: May 23, 2014, 07:16:58 PM »
Factor is never 0. Look at the function I posted. If you played it in reverse before, amount per delta will be negative, so factor will be set to 1 by ResetToBeginning(), not 0. That function depends on what the "beginning" was. If you played it forward, 'beginning' is factor 0 after. If you played it in reverse, beginning is 1.

I also asked what version of NGUI do you have?

3.5.8

that's my point, if match all the condition, the factor is 0 instead 1

* the tween is never played before( in my case it's disabled on prefab )
* the user play the tween in reverse( again, the tween never played before )
* the user want to ResetToBeginning everytime the tween is played

the code will like this one:
  1. // -- somescript.cs, a gui controller --
  2. // *1
  3. private void Show()
  4. {
  5.    _tween.ResetToBeginning();
  6.    _tween.PlayReverse();
  7. }
  8. // or like this, *2
  9. private void Show()
  10. {
  11.    _tween.PlayReverse();
  12.    _tween.ResetToBeginning();
  13. }
  14.  

in *1, the factor is set to 0f, and the tween will be played, BUT stop right away and fire event
===>
in one frame
1.ResetToBeginning()-> make factor 0f ( because PlayReverse() is not called yet )
2.PlayReverse()-> make amountPerDelta < 0f
3.update() called by PlayReverse()-> mFactor += amountPerDelta * delta;
              -> make mFactor < 0f;
              -> tween stopped


in *2, the factor is set to 1f AFTER ResetToBeginning,
but the FIRST update in PlayReverse(), mFactor += amountPerDelta * delta;
mFactor will be negative, and stop the tween

====>
also in one frame
1.PlayReverse()-> amountPerDelta < 0f
2.update() called by PlayReverse()-> mFactor += amountPerDelta * delta;
              -> mFactor < 0f;
              -> stopped
3.ResetToBeginning()-> make factor 1f ( because PlayReverse() is called )
              -> BUT THE TWEEN IS ALREADY STOPPED, set to 1f is too late now


that makes users have to play PlayReverse() 2 times if the tween is first time played
of couse i can check the "first time play" in my Show(),
but i think this should be controlled by NGUI, instead of user.
users don't have to check the "first time play" everywhere if they notice the might play a tween in reverse in the very fist time

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #11 on: May 23, 2014, 09:31:42 PM »
Ah, the key is that you're trying to play a tween in reverse that hasn't been played before. Playing the tween in revese takes its current position (factor, which is 0 to start with). Reverse makes target also be 0, and that effectively means that there is no point in tweening since it's already at the target position. If the factor was '1' to start with, then it would behave as expected.

So instead of calling ResetToBeginning() you should be simply setting UITween's factor.

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #12 on: May 24, 2014, 09:27:46 AM »
yes, that's what i mean.

but i think it's weird here,
shouldn't the ResetToBegginning() and Play() work instead of user need to check by themselves?

-- what i think it should be
  1. private void Show()
  2. {
  3.    _tween.PlayReverse();
  4.    _tween.ResetToBeginning();
  5. }
  6.  

-- what the NGUI 3.5.8 wants me to do ( or in another word: i have to do )
  1. private void Show()
  2. {
  3.    _tween.PlayReverse();
  4.    _tween.ResetToBeginning();
  5.    _tween.PlayReverse();
  6. }
  7.  
  8. //or
  9. bool _firstTime = true;
  10. private void Show()
  11. {
  12.    if( _firstTime )
  13.       tweenFactor = 1f;
  14.    _tween.PlayReverse();
  15.    _tween.ResetToBeginning();
  16. }
  17.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #13 on: May 24, 2014, 04:09:11 PM »
  1. _tween.factor = 1f;
  2. _tween.PlayReverse();
...should be enough.

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: UITweener.ResetToBeginning() / UITweener.current issue
« Reply #14 on: May 24, 2014, 09:12:19 PM »
i got you now.
in there few days, i found that what i need is just a overload function of ResetToBeginning()
could you consider that?

  1.     public void Play (bool forward)
  2.     {
  3. *       SetDirection( forward );
  4.         enabled = true;
  5.         Update();
  6.     }
  7.  
  8. +   public void SetDirection(bool forward)
  9. +   {
  10. +       mAmountPerDelta = Mathf.Abs(amountPerDelta);
  11. +       if (!forward) mAmountPerDelta = -mAmountPerDelta;
  12. +   }
  13.  
  14.     public void ResetToBeginning ()
  15.     {
  16.         mStarted = false;
  17.         mFactor = (mAmountPerDelta < 0f) ? 1f : 0f;
  18.         Sample(mFactor, false);
  19.     }
  20.  
  21. +   public void ResetToBeginning ( bool forward )
  22. +   {
  23. +       SetDirection( forward );
  24. +       ResetToBeginning ();
  25. +   }
  26.