As far as I can tell, it's impossible to reset a tween after it has been played in reverse. The easiest way to explain is probably just a code example. I have a popup window that tweens in, waits for a couple seconds, and tweens back out (in reverse). If it's called while already active, it queues the new message and shows it after the current one finishes. If the user leaves the screen it's on, the queue is simply emptied. This means it's possible for the tween to have been disabled in some random state and needs to be reset to it's initial state before being shown.
using System.Collections.Generic;
using UnityEngine;
public class PopupTest : MonoBehaviour
{
#region Editor Interface
[SerializeField] private TweenScale tweener;
[SerializeField] private int secondsToDisplay;
#endregion
#region Private Fields
private static PopupTest instance;
private static Queue
<string> queue
= new Queue
<string>(); private static bool isActive = false;
#endregion
#region MonoBehaviour Methods
private void Awake ()
{
//Enforce the singleton pattern
if ( instance != null )
{
Debug.LogError("Multiple instances of the " + GetType() + " created. There can be only one.");
}
instance = this;
}
private void OnDisable ()
{
isActive = false;
NGUITools.SetActiveChildren(gameObject, false);
tweener.onFinished.Clear();
tweener.enabled = false;
queue.Clear();
}
private void OnDestroy ()
{
instance = null;
}
#endregion
#region Public Interface
public static void Display ()
{
if ( !instance.gameObject.activeInHierarchy ) return;
queue.Enqueue("Test");
if ( !isActive )
{
instance.Show();
}
}
#endregion
#region Private Methods
private void Show ()
{
queue.Dequeue();
EventDelegate.Add(tweener.onFinished, Hide, true);
tweener.delay = 0;
tweener.Play(true);
Debug.Log("Scale (play1):" + transform.localScale);
tweener.ResetToBeginning();
Debug.Log("Scale (reset):" + transform.localScale);
tweener.Play(true);
Debug.Log("Scale (play2):" + transform.localScale);
isActive = true;
NGUITools.SetActiveChildren(gameObject, true);
}
private void Hide ()
{
EventDelegate.Add(tweener.onFinished, HideComplete, true);
tweener.delay = secondsToDisplay;
tweener.Play(false);
}
private void HideComplete ()
{
isActive = false;
NGUITools.SetActiveChildren(gameObject, false);
if ( queue.Count > 0 )
{
Show();
}
}
#endregion
}
The issues are with Show(). Since the tween could have been disabled while tweening in reverse, I have to play it forward once otherwise ResetToBeginning actually resets it to the end. However, it still doesn't work. If the tween is disabled in the middle of the tween playing in reverse, I can't get it to reset back to the beginning and it will just appear instantly instead of tweening.
Incidentally, if you remove the first Play(true) from Show() the tween will throw an exception when a message is queued.