Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Suggested feature: being able to mix Button's Animation transition with Sprite Swap and Tint

Discussion in 'UGUI & TextMesh Pro' started by CanisLupus, Oct 22, 2014.

  1. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    A common procedure in a game is to standardize the behavior of buttons when pressed/hovered/disabled, etc. In Unity's uGUI we can create a generic animator for every button in the game, setting the Button's transition to "Animation". This animator can slightly scale the button on hover, reduce and darken it on press, apply alpha on disable, etc.

    It is also very common for buttons to have different sprites when pressed, hovered, etc. To this end, we can use the "Sprite Swap" transition. However, we cannot use both Sprite Swap and Animation! This makes it impossible to keep a generic behavior with personalized sprites.

    I believe this is a common enough need that it should be implemented natively. I posted a question here and the best option yet was to create a new button script (inheriting from Button) and overriding/recreating DoStateTransition or whichever method is best suited for this.

    Is there a "best" way to do this? Is it a planned feature?

    Best regards,
    Daniel
     
    AlanCDev and KayelGee like this.
  2. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    if its set up as a animation you can change the sprite via the animation window as well. Just add the image .sprite to the animations and it will switch between them. |

    Am i missing something here?
     
  3. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    If the state animations contain sprite changes they will stop being generic right then. That would require an animator and set of animations for each different button (because each button has different sprites). The scalings/tints/etc must be the same for every button (a single Animator), but each button has its own set of sprites.

    Is this clearer?
     
  4. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    In terms of it not being generic any more you're right. ATM you'd need to do as the other forum post said with creating your own button class.

    If you want submit a feature request for it although it won't get done for v1.
     
  5. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    I proposed the feature here, in case somebody else is also interested. Thanks.
     
    mr_blahblah likes this.
  6. Greire

    Greire

    Joined:
    Nov 14, 2014
    Posts:
    6
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.Events;
    using UnityEngine.EventSystems;
    using System.Collections;

    public class ButtonMT : Button {

    protected override void DoStateTransition (SelectionState state, bool instant)
    {
    // Button Mixed Transition

    Sprite stateSprite = null;
    switch( state )
    {
    case SelectionState.Normal:
    stateSprite = null;
    break;
    case SelectionState.Disabled:
    stateSprite = spriteState.disabledSprite;
    break;
    case SelectionState.Highlighted:
    stateSprite = spriteState.highlightedSprite;
    break;
    case SelectionState.Pressed:
    stateSprite = spriteState.pressedSprite;
    break;
    }

    if( null == stateSprite )
    {
    if( transition == Transition.SpriteSwap )
    {
    base.DoStateTransition (SelectionState.Normal, instant);
    }
    transition = Transition.ColorTint;
    }
    else
    {
    if( transition == Transition.ColorTint )
    {
    base.DoStateTransition (SelectionState.Normal, instant);
    }
    transition = Transition.SpriteSwap;
    }

    base.DoStateTransition (state, instant);
    }
    }


    i try make tint and swap. it works but custom properties not expose and transition not change in inspector.
    i use serializable attribute but same.
     
  7. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    The best I created is the following script. It only mixes Animation and SpriteSwap, and requires that you set the sprites in the SpriteSwap transition of the button (in the inspector) and then change it to the Animation transition when finished. This is because I haven't found a way to execute the transition Animations correctly from code, so I rely on the internal implementation of DoStateTransition() to do that. On the other hand, sprite swapping is easy enough to do.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. public class SpriteSwapperButton : Button
    5. {
    6.    private Sprite normalSprite;
    7.  
    8.    protected override void Awake()
    9.    {
    10.      base.Awake();
    11.      normalSprite = image.sprite;
    12.    }
    13.  
    14.    protected override void DoStateTransition (Selectable.SelectionState state, bool instant)
    15.    {
    16.      base.DoStateTransition(state, instant);
    17.  
    18.      Sprite newSprite = null;
    19.  
    20.      switch (state)
    21.      {
    22.        case Selectable.SelectionState.Normal:
    23.          newSprite = normalSprite;
    24.          break;
    25.        case Selectable.SelectionState.Highlighted:
    26.          newSprite = this.spriteState.highlightedSprite;
    27.          break;
    28.        case Selectable.SelectionState.Pressed:
    29.          newSprite = this.spriteState.pressedSprite;
    30.          break;
    31.        case Selectable.SelectionState.Disabled:
    32.          newSprite = this.spriteState.disabledSprite;
    33.          break;
    34.      }
    35.  
    36.      if (newSprite != null) {
    37.        image.sprite = newSprite;
    38.      }
    39.    }
    40. }
    41.  
    Warning: This is far from perfect, and might create some problem I'm not aware of.

    If you want to use this script but don't want to remove your existing Button components first, set the inspector in Debug mode (beside the lock symbol in the top right corner, press and select "Debug" instead of "Normal") and then exchange the Button script for the SpriteSwapperButton. If done correctly, this will retain all values from your Button.

    Looking forward to other/better approaches to this!
     
  8. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    823
    Hey there,

    I've got the same problem, but I want to use animations and Tint color at the same time. My solution is, to do the animation handling via a script. It is pretty simple, but maybe it helps somebody as a starting point:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.EventSystems;
    3. using System.Collections;
    4.  
    5. public class ButtonAnimator : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler {
    6.     private Animator buttonAnimator;
    7.     // Use this for initialization
    8.     void Start () {
    9.         buttonAnimator = GetComponent<Animator>();
    10.     }
    11.  
    12.     public void OnPointerEnter (PointerEventData eventData) {
    13.         buttonAnimator.SetTrigger("Highlighted");
    14.     }
    15.  
    16.     public void OnPointerExit (PointerEventData eventData) {
    17.         buttonAnimator.SetTrigger("Normal");
    18.     }
    19.  
    20.     public void OnPointerDown (PointerEventData eventData) {
    21.         buttonAnimator.SetTrigger("Pressed");
    22.     }
    23. }
    24.  
    Not complete, because I will use other states, but I guess an easy way to do it :)
     
    Torquer likes this.
  9. denlee0710

    denlee0710

    Joined:
    Mar 9, 2015
    Posts:
    36