Tasharen Entertainment Forum

Support => NGUI 3 Support => Topic started by: gyd on May 08, 2014, 03:30:19 AM

Title: UITweener.ResetToBeginning() / UITweener.current issue
Post by: gyd 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.
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: ArenMook 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.
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: gyd 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.
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: ArenMook 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;
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: gyd 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.

Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: gyd on May 14, 2014, 07:44:04 AM
is this a BUG?
i think it should check the direction when played for first time.
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: ArenMook 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?
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: gyd 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.  
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: gyd on May 22, 2014, 09:05:06 PM
please read the reply, i would like know the condition of the UITweener issues, thanks.
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: ArenMook 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?
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: gyd 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
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: ArenMook 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.
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: gyd 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.  
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: ArenMook on May 24, 2014, 04:09:11 PM
  1. _tween.factor = 1f;
  2. _tween.PlayReverse();
...should be enough.
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: gyd 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.  
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: ArenMook on May 25, 2014, 05:40:18 PM
I don't understand... you want me to add an entire new function because you don't want to call "_tween.factor = 1f;" ?
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: gyd on May 25, 2014, 09:14:11 PM
i am just think that users need some debug to find out they can't PlayReverse() at the first time,
and add _tween.factor = 1f, like me.

but they don't need to add _tween.factor = 0f, when they PlayForward() at the first time.

the ResetToBeginning() overloading suggesting may not a good solution for this issue ( in fact i said that just because i saw someone request the overload before, sorry )

let the problem simpler,
consider a user create a tween and disable it, he may want the tween be played for only once.

his script may just like this and makes sense:
  1. void SomeFunction()
  2. {
  3.     if( someCheck )
  4.         _tween.PlayForward();
  5.     else
  6.         _tween.PlayReverse();
  7. }
  8.  

but it should be in 3.5.8

  1. void SomeFunction()
  2. {
  3.     if( someCheck )
  4.         _tween.PlayForward();
  5.     else
  6.     {
  7.         _tween.factor = 1f;
  8.         _tween.PlayReverse();
  9.     }
  10. }
  11.  

again, sorry about my last reply, that didn't solve my question.
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: ArenMook on May 26, 2014, 11:57:19 PM
If the tween is already at A, there is no point in going from B to A using PlayReverse(), because there will be a visual "jump" where tween gets to the end then plays back to the start. If I was to change it to jump to the end, then the button hover animation would effectively break as well.

Think hovering over a button, then halfway through that hover animation, moving the mouse away. With the reset to factor of 1, there will now be an obvious jump to the final state before tweening back to the start. This is not ideal. What should happen is the current position of the tween should be used as the starting point, and only the direction should be reversed, making the transition seamless and invisible. So the end result would be going from A tween halfway to B, then back to A, rather than A tween halfway to B, jump to B, then tween to A.

Bottom line is if you want this jump, then you should request it by setting factor to 1. In most cases you won't want to, which is why it's the default behaviour.
Title: Re: UITweener.ResetToBeginning() / UITweener.current issue
Post by: gyd on May 27, 2014, 12:58:59 AM
okay thanks.