Hello Guest

Author Topic: Proper way to code my own tween for UI Item  (Read 5554 times)

edb

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 43
    • View Profile
Proper way to code my own tween for UI Item
« on: October 26, 2014, 09:37:45 pm »
I'm trying to code my own tween for when a button is clicked.  I want it to move down in Y instead of scale, so I can't use the UITweenItem script.  So I'm writing my own -  I modified UITweenItem to also support moves, and it works, but just one time, and then I keep getting the error in the attached screenshot.  I also tried duplicating the the UITweenItem, renaming it UITweenItem_Move, then modifying it for moves, but I also get the same error.

Any thoughts?

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Proper way to code my own tween for UI Item
« Reply #1 on: October 27, 2014, 09:20:21 am »
I can't guess how you've done this, it shouldn't cause any issues - we have our own library of tweens we pick from internally and that works fine for us - post a repro case and I could look into it for you.

edb

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 43
    • View Profile
Re: Proper way to code my own tween for UI Item
« Reply #2 on: October 27, 2014, 02:37:22 pm »
Here's the code where I modified the UITweenItem script to also support move offsets:

Code: [Select]
using UnityEngine;
using System.Collections;

/// <summary>
/// Will scale uiItem up and down, on press events
/// </summary>
[AddComponentMenu("2D Toolkit/UI/tk2dUITweenItem")]
public class tk2dUITweenItem : tk2dUIBaseItemControl
{
    private Vector3 onUpScale; //keeps track of original scale
    private Vector3 onUpMove; //keeps track of original position

    /// <summary>
    /// What it should scsale to onDown event
    /// </summary>
    public Vector3 onDownScale = new Vector3(.9f, .9f, .9f);

    /// <summary>
    /// What it should move to onDown event
    /// </summary>
    public Vector3 onDownOffsetAmt = new Vector3(5.0f, -5.0f, 0);

    /// <summary>
    /// How long the tween (scaling) should last in seconds. If set to 0 no tween is used, happens instantly.
    /// </summary>
    public float tweenDuration = .1f;

    /// <summary>
    /// If button can be held down (will not be scale back to original until up/release)
    /// Can not be toggled at run-time
    /// </summary>
    public bool canButtonBeHeldDown = true; //can not be toggled at runtime

    /// <summary>
    /// If using canButtonBeHeldDown, if the scale back to original should happen onRelease event instead of onUp event
    /// </summary>
    [SerializeField]
    private bool useOnReleaseInsteadOfOnUp = false;

    public bool UseOnReleaseInsteadOfOnUp
    {
        get { return useOnReleaseInsteadOfOnUp; }
    }

    private bool internalTweenInProgress = false;

    private Vector3 tweenTargetScale = Vector3.one;
    private Vector3 tweenStartingScale = Vector3.one;

    private Vector3 tweenTargetMove = Vector3.one;
    private Vector3 tweenStartingMove = Vector3.one;


    private float tweenTimeElapsed = 0;

    //------------------------------------------------------------
    void Awake()
    {
        onUpScale = transform.localScale;
onUpMove = transform.localPosition;
     }
    //------------------------------------------------------------

   //------------------------------------------------------------
   void OnEnable()
    {
        if (uiItem)
        {
            uiItem.OnDown += ButtonDown;
            if (canButtonBeHeldDown)
            {
                if (useOnReleaseInsteadOfOnUp)
                {
                    uiItem.OnRelease += ButtonUp;
                }
                else
                {
                    uiItem.OnUp += ButtonUp;
                }
            }
        }
        internalTweenInProgress = false;
        tweenTimeElapsed = 0;

        transform.localScale = onUpScale;
transform.localPosition = onUpMove;
     }
    //------------------------------------------------------------

    //------------------------------------------------------------
    void OnDisable()
    {
        if (uiItem)
        {
            uiItem.OnDown -= ButtonDown;
            if (canButtonBeHeldDown)
            {
                if (useOnReleaseInsteadOfOnUp)
                {
                    uiItem.OnRelease -= ButtonUp;
                }
                else
                {
                    uiItem.OnUp -= ButtonUp;
                }
            }
        }
    }
   //------------------------------------------------------------

   //------------------------------------------------------------
   private void ButtonDown()
    {
        if (tweenDuration <= 0)
        {
            transform.localScale = onDownScale;
    transform.localPosition = onUpMove + onDownOffsetAmt;
}
        else
        {
            transform.localScale = onUpScale;
    transform.localPosition = onUpMove;

            tweenTargetScale = onDownScale;
            tweenStartingScale = transform.localScale;

    tweenTargetMove = onUpMove + onDownOffsetAmt;
    tweenStartingMove = transform.localPosition;


            if (!internalTweenInProgress)
            {
                StartCoroutine(ScaleTween());
        StartCoroutine(MoveTween());
internalTweenInProgress = true;
            }
        }
    }
   //------------------------------------------------------------

   //------------------------------------------------------------
   private void ButtonUp()
    {
        if (tweenDuration <= 0)
        {
            transform.localScale = onUpScale;
    transform.localPosition = onUpMove;
}
        else
        {
            tweenTargetScale = onUpScale;
            tweenStartingScale = transform.localScale;

    tweenTargetMove = onUpMove;
    tweenStartingMove = transform.localPosition;

            if (!internalTweenInProgress)
            {
                StartCoroutine(ScaleTween());
StartCoroutine(MoveTween());
internalTweenInProgress = true;
            }     
        }
    }
    //------------------------------------------------------------

    //------------------------------------------------------------
    private IEnumerator ScaleTween()
    {
        tweenTimeElapsed = 0;
        while (tweenTimeElapsed < tweenDuration)
        {
            transform.localScale = Vector3.Lerp(tweenStartingScale,tweenTargetScale,tweenTimeElapsed / tweenDuration);
            yield return null;
            tweenTimeElapsed += tk2dUITime.deltaTime;
        }
        transform.localScale = tweenTargetScale;
        internalTweenInProgress = false;

        //if button is not held down bounce it back
        if (!canButtonBeHeldDown)
        {
            if (tweenDuration <= 0)
            {
                transform.localScale = onUpScale;
            }
            else
            {
                tweenTargetScale = onUpScale;
                tweenStartingScale = transform.localScale;
                StartCoroutine(ScaleTween());
                internalTweenInProgress = true;
            }
        }
    }
    //------------------------------------------------------------
    //------------------------------------------------------------
    private IEnumerator MoveTween()
    {
tweenTimeElapsed = 0;
while (tweenTimeElapsed < tweenDuration)
{
//transform.localScale = Vector3.Lerp(tweenStartingScale,tweenTargetScale,tweenTimeElapsed / tweenDuration);
transform.localPosition = Vector3.Lerp(tweenStartingMove,tweenTargetMove,tweenTimeElapsed / tweenDuration);
yield return null;
tweenTimeElapsed += tk2dUITime.deltaTime;
}
  //transform.localScale = tweenTargetScale;
  transform.localPosition = tweenTargetMove;
internalTweenInProgress = false;

//if button is not held down bounce it back
if (!canButtonBeHeldDown)
{
if (tweenDuration <= 0)
  {
//transform.localScale = onUpScale;
  transform.localPosition = onUpMove;
}
else
{
//tweenTargetScale = onUpScale;
tweenTargetMove = onUpMove;
//tweenStartingScale = transform.localScale;
tweenStartingMove = transform.localPosition;
StartCoroutine(MoveTween());
internalTweenInProgress = true;
}
}
}
//------------------------------------------------------------


//------------------------------------------------------------
/// <summary>
        /// Internal do not use
       /// </summary>
        public void InternalSetUseOnReleaseInsteadOfOnUp(bool state)
       {
            useOnReleaseInsteadOfOnUp = state;
        }
//------------------------------------------------------------

}



That's all I'm doing...maybe there's something else somewhere I need to change?
« Last Edit: October 27, 2014, 02:43:00 pm by edb »

edb

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 43
    • View Profile
Re: Proper way to code my own tween for UI Item
« Reply #3 on: October 27, 2014, 03:39:51 pm »
I'm using Unity 4.5.5, by the way...

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Proper way to code my own tween for UI Item
« Reply #4 on: October 28, 2014, 05:34:53 pm »
Hi,

I just tried this out and dont seem to be able to reproduce it - it seems to behave itself properly and I dont see any errors. In any case, the error you're seeing isn't a critical one - it suggests that the material is being destroyed inside one frame - its Unitys inspector that is complaining, and it shouldn't really cause any real issues as far as I can tell... If you can try to create a scene that breaks I'll be happy to look, ideally with as little stuff as possible - that usually identifies the issue.

edb

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 43
    • View Profile
Re: Proper way to code my own tween for UI Item
« Reply #5 on: October 28, 2014, 06:41:54 pm »
I tried out the script again after cleaning the build (by deleting the contents of the library folder) and it's working without errors!

For whoever's info - I also added this line to tk2dUITweenItemEditor.cs:

Code: [Select]
btnClickScaler.onDownOffsetAmt = EditorGUILayout.Vector3Field("On Down Offset Amt", btnClickScaler.onDownOffsetAmt);

edb

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 43
    • View Profile
Re: Proper way to code my own tween for UI Item
« Reply #6 on: October 28, 2014, 07:12:02 pm »
Also my previous modifications were a bit wonky - this works better:

Code: [Select]
using UnityEngine;
using System.Collections;

/// <summary>
/// Will move and scale uiItem up and down, on press events
/// </summary>
[AddComponentMenu("2D Toolkit/UI/tk2dUITweenItem")]
public class tk2dUITweenItem : tk2dUIBaseItemControl
{
    private Vector3 onUpScale; //keeps track of original scale
    private Vector3 onUpMove; //keeps track of original position

    /// <summary>
    /// What it should scale to onDown event
    /// </summary>
    public Vector3 onDownScale = new Vector3(1, 1, 1);

/// <summary>
/// How much it should move/offset onDown event
/// </summary>
public Vector3 onDownOffsetAmt = new Vector3(0.0f, -3.5f, 0);

    /// <summary>
    /// How long the tween (scaling) should last in seconds. If set to 0 no tween is used, happens instantly.
    /// </summary>
    public float tweenDuration = 0.06f;

    /// <summary>
    /// If button can be held down (will not be scale back to original until up/release)
    /// Can not be toggled at run-time
    /// </summary>
    public bool canButtonBeHeldDown = true; //can not be toggled at runtime

    /// <summary>
    /// If using canButtonBeHeldDown, if the scale back to original should happen onRelease event instead of onUp event
    /// </summary>
    [SerializeField]
    private bool useOnReleaseInsteadOfOnUp = false;

    public bool UseOnReleaseInsteadOfOnUp
    {
        get { return useOnReleaseInsteadOfOnUp; }
    }

    private bool internalTweenInProgress = false;

    private Vector3 tweenTargetScale = Vector3.one;
    private Vector3 tweenStartingScale = Vector3.one;

     private Vector3 tweenTargetMove = Vector3.one;
     private Vector3 tweenStartingMove = Vector3.one;


    private float tweenTimeElapsed = 0;

//------------------------------------------------------------
void Awake()
       {
           onUpScale = transform.localScale;
   onUpMove = transform.localPosition;
}
//------------------------------------------------------------

//------------------------------------------------------------
void OnEnable()
       {
        if (uiItem)
        {
            uiItem.OnDown += ButtonDown;
            if (canButtonBeHeldDown)
            {
                if (useOnReleaseInsteadOfOnUp)
                {
                    uiItem.OnRelease += ButtonUp;
                }
                else
                {
                    uiItem.OnUp += ButtonUp;
                }
            }
        }
        internalTweenInProgress = false;
        tweenTimeElapsed = 0;

        transform.localScale = onUpScale;
transform.localPosition = onUpMove;
}
//------------------------------------------------------------

//------------------------------------------------------------
void OnDisable()
       {
        if (uiItem)
        {
            uiItem.OnDown -= ButtonDown;
            if (canButtonBeHeldDown)
            {
                if (useOnReleaseInsteadOfOnUp)
                {
                    uiItem.OnRelease -= ButtonUp;
                }
                else
                {
                    uiItem.OnUp -= ButtonUp;
                }
            }
        }
    }
   //------------------------------------------------------------

   //------------------------------------------------------------
   private void ButtonDown()
    {
        if (tweenDuration <= 0)
        {
            transform.localScale = onDownScale;
    transform.localPosition = onUpMove + onDownOffsetAmt;
}
        else
        {
            transform.localScale = onUpScale;
    transform.localPosition = onUpMove;

            tweenTargetScale = onDownScale;
            tweenStartingScale = transform.localScale;

    tweenTargetMove = onUpMove + onDownOffsetAmt;
    tweenStartingMove = transform.localPosition;


            if (!internalTweenInProgress)
            {
                StartCoroutine(ScaleAndMoveTween());
internalTweenInProgress = true;
            }
        }
    }
//------------------------------------------------------------

//------------------------------------------------------------
private void ButtonUp()
    {
        if (tweenDuration <= 0)
        {
             transform.localScale = onUpScale;
     transform.localPosition = onUpMove;
}
        else
        {
            tweenTargetScale = onUpScale;
            tweenStartingScale = transform.localScale;

    tweenTargetMove = onUpMove;
    tweenStartingMove = transform.localPosition;

            if (!internalTweenInProgress)
            {
StartCoroutine(ScaleAndMoveTween());
internalTweenInProgress = true;
            }     
        }
    }
//------------------------------------------------------------

//------------------------------------------------------------
private IEnumerator ScaleAndMoveTween()
    {
        tweenTimeElapsed = 0;
        while (tweenTimeElapsed < tweenDuration)
        {
             transform.localScale = Vector3.Lerp(tweenStartingScale,tweenTargetScale,tweenTimeElapsed / tweenDuration);
     transform.localPosition = Vector3.Lerp(tweenStartingMove,tweenTargetMove,tweenTimeElapsed / tweenDuration);
     yield return null;
            tweenTimeElapsed += tk2dUITime.deltaTime;
        }
           transform.localScale = tweenTargetScale;
   transform.localPosition = tweenTargetMove;
    internalTweenInProgress = false;

        //if button is not held down bounce it back
        if (!canButtonBeHeldDown)
        {
            if (tweenDuration <= 0)
            {
                transform.localScale = onUpScale;
transform.localPosition = onUpMove;
    }
            else
            {
                tweenTargetScale = onUpScale;
tweenTargetMove = onUpMove;
tweenStartingScale = transform.localScale;
tweenStartingMove = transform.localPosition;
StartCoroutine(ScaleAndMoveTween());
                internalTweenInProgress = true;
            }
        }
    }
//------------------------------------------------------------

//------------------------------------------------------------
/// <summary>
    /// Internal do not use
    /// </summary>
    public void InternalSetUseOnReleaseInsteadOfOnUp(bool state)
    {
        useOnReleaseInsteadOfOnUp = state;
    }
//------------------------------------------------------------

}