Author Topic: Workaround for flickering animation!  (Read 6704 times)

kruncher

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 78
    • View Profile
Workaround for flickering animation!
« on: December 14, 2013, 07:32:49 PM »
Hey all

I have an NGUI window with an animation which plays each time the window is shown. I am essentially animating the alpha colour of two sprite objects. Whilst this looks great I was experiencing a rapid flicker for a split second at the start of the animation.

It seems that this was caused because upon enabling my window object, NGUI updates its mesh representation of the window from its last known state, then the animation kicks in and tweaks the values, then NGUI re-updates to the new known state.

So I thought I would share my workaround should anybody else need to know:
  • Insert a keyframe at the very start of your animation for each widget which experiences some sort of flicker (or for some shared root object) to deactivate the game object.
  • In the next animation frame, setup the initial alpha colour. The widgets are deactivated, so no flicker will occur whilst making this change.
  • In the next keyframe re-activate the game objects again.
The above steps remove he unsightly flicker simply by introducing two keyframes which elapse almost instantly.

I hope that this helps future readers :)

kruncher

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 78
    • View Profile
Re: Workaround for flickering animation!
« Reply #1 on: January 07, 2014, 02:36:47 AM »
Since the latest asset store release of NGUI 3.0.8f5 this workaround no longer works.

Given an animation which smoothly fades the colour (using the "Animated Color" component) the following happens:

- Enable game object to trigger animation.
- NGUI components appear for a brief instance.
- First frame of animation sets alpha to 0, NGUI components gone again.
- NGUI components smoothly fade in.

There is a brief instance at the start of the animation where the NGUI components appear, then disappear.

To reproduce:

1. Create an animation to some parent game object using the animation window.
2. Set alpha to 0 in first frame of animation and 1 in last frame.
3. Trigger animation upon enabling the parent game object during game.
4. Experience flicker.

Flicker does not occur when playing animation using the animation window's play button. The flicker only occurs when enabling the game object to trigger playback of the animation.

Any ideas for a workaround?

kruncher

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 78
    • View Profile
Re: Workaround for flickering animation!
« Reply #2 on: January 07, 2014, 03:33:17 AM »
Okay, I have found a workaround for my project, but this is definitely a bug.

Instead of animating the alpha using the animation window, I have replaced the "AnimatedAlpha" component with the following custom component. This does not exhibit the ghastly flicker:

  1. using UnityEngine;
  2.  
  3. public class AnimatedAlphaAutoReset : MonoBehaviour {
  4.  
  5.         public float startAlpha = 1f;
  6.         public float finishAlpha = 1f;
  7.         public float duration = 0.2f;
  8.  
  9.         private UIWidget _widget;
  10.         private UIPanel _panel;
  11.  
  12.         private bool _hasInit;
  13.         private float _elapsed;
  14.  
  15.         private void OnEnable() {
  16.                 if (!_hasInit) {
  17.                         _hasInit = true;
  18.                         _widget = GetComponent<UIWidget>();
  19.                         _panel = GetComponent<UIPanel>();
  20.                 }
  21.  
  22.                 _elapsed = 0f;
  23.  
  24.                 SetAlpha(startAlpha);
  25.         }
  26.  
  27.         private void Update() {
  28.                 _elapsed = Mathf.Min(duration, _elapsed + Time.deltaTime);
  29.  
  30.                 float progress = _elapsed / duration;
  31.                 float alphaRange = finishAlpha - startAlpha;
  32.                 SetAlpha(startAlpha + alphaRange * progress);
  33.         }
  34.  
  35.         private void SetAlpha(float value) {
  36.                 if (_widget != null)
  37.                         _widget.alpha = value;
  38.                 if (_panel != null)
  39.                         _panel.alpha = value;
  40.         }
  41.  
  42. }
  43.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Workaround for flickering animation!
« Reply #3 on: January 07, 2014, 09:17:21 AM »
Easiest fix is to ensure that your widget start with the alpha of 0 to begin with, not just have the animation set it to 0 while widget start with 1.

kruncher

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 78
    • View Profile
Re: Workaround for flickering animation!
« Reply #4 on: January 07, 2014, 11:50:13 AM »
There are two problems with this:

1. The fix only seems to work the very first time the GUI is shown. There needs to be a script in place to reset the alpha value back to zero.

2. Becomes tricky to maintain in-editor since it becomes necessary to temporarily restore the alpha to 100% in order to adjust and maintain the GUI.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Workaround for flickering animation!
« Reply #5 on: January 08, 2014, 01:31:00 PM »
True. By the way, you can achieve the same fix as your code by adding the following line to the AnimatedAlpha script:
  1. void OnEnable () { Update(); }
...or just renaming its Awake() function to OnEnable(). It's a tiny script, feel free to modify it or make a copy and modify that. In any case I'll also add this line to the next release.

Brakeley

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 3
    • View Profile
Re: Workaround for flickering animation!
« Reply #6 on: February 27, 2014, 02:33:49 PM »
I'm seeing this exact issue in 3.4.8.  Has it been addressed in a newer release?

I just locally changed AnimateColor.cs to use LateUpdate instead of Update, and it appears to have fixed the problem.  I believe Unity first calls all Updates, then updates the animations, then calls all LateUpdates, and finally renders, which would explain where this problem comes from.

So now AnimateColor.cs looks like this:

  1. //----------------------------------------------
  2. //            NGUI: Next-Gen UI kit
  3. // Copyright © 2011-2014 Tasharen Entertainment
  4. //----------------------------------------------
  5.  
  6. using UnityEngine;
  7.  
  8. /// <summary>
  9. /// Makes it possible to animate a color of the widget.
  10. /// </summary>
  11.  
  12. [ExecuteInEditMode]
  13. [RequireComponent(typeof(UIWidget))]
  14. public class AnimatedColor : MonoBehaviour
  15. {
  16.         public Color color = Color.white;
  17.        
  18.         UIWidget mWidget;
  19.  
  20.         void OnEnable () { mWidget = GetComponent<UIWidget>(); LateUpdate(); }
  21.         void LateUpdate () { mWidget.color = color; }
  22. }

If it needs to happen in Update() for some reason, maybe it could happen in both?  Or expose an option on AnimateColor.cs to let the user choose from the Inspector?
« Last Edit: February 27, 2014, 02:44:53 PM by Brakeley »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Workaround for flickering animation!
« Reply #7 on: February 27, 2014, 04:51:55 PM »
Please update to the latest before posting about issues. 3.0.8 is from December. This post is from January.

Brakeley

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 3
    • View Profile
Re: Workaround for flickering animation!
« Reply #8 on: February 27, 2014, 05:43:26 PM »
Hey, sorry, if I need to start a new thread, I can do that.  It's just that I got here via google, and figured others might end up here as well.  As kruncher said in her/his last post, the proposed workarounds rely on saving prefabs in a known state, which isn't a great workflow, especially for a larger sized team.

And as I said, I'm using 3.4.8, which is only a few weeks old.  I'm on a large project, and we avoid pulling down new third-party code without a reason.  I can setup a test environment on my end to try out 3.5.1 if that is the only way to know, but I was hoping that someone on this forum might know the status of this issue off hand.

My fix seems to be working great locally, but I wasn't sure if moving to LastUpdate() might break something else?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Workaround for flickering animation!
« Reply #9 on: February 27, 2014, 06:06:21 PM »
Actually sorry, my fault. I thought it was regarding something else. So animation updates happen after regular updates? Interesting. Your code makes sense then, thanks!

Brakeley

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 3
    • View Profile
Re: Workaround for flickering animation!
« Reply #10 on: February 27, 2014, 06:24:24 PM »
Hey, no problem.  Yeah, I found order of op stuff here: http://answers.unity3d.com/questions/38432/exact-order-of-operations-to-render-a-frame-charac.html.

That discussion quotes the Unity manual thusly:

Quote
So in conclusion, this is the execution order for any given script:
  • All Awake calls
  • All Start Calls
  • while (stepping towards variable delta time)
    • All FixedUpdate functions
    • Physics simulation
    • OnEnter/Exit/Stay trigger functions
    • OnEnter/Exit/Stay collision functions
  • Rigidbody interpolation applies transform.position and rotation
  • OnMouseDown/OnMouseUp etc. events
  • All Update functions
  • Animations are advanced, blended and applied to transform
  • All LateUpdate functions
  • Rendering