0
\$\begingroup\$

I am trying to create a UI Button Prefab with a text child element that I would like to use all over my application. Its intended behavior is very simple:

  • Its size would be dependent on the text's width (this has been achieved using content size fitter and a horizontal layout group).
  • Its states would be done using sprite swap (this had also been done partly)

enter image description here

The problem is that the pressed state uses an image on which the button is visually pressed (its top moves downward a few pixels). This is a nice effect and the image works great, however, I cannot make the text move in synchrony with the image to sell the downward movement.

My way of thinking was to use an initial padding of 4 at the bottom in the horizontal layout group (to move the text upward) then change it to 2 when the button enters a pressed state. Something like this:

using UnityEngine.UI;

public class ButtonController : MonoBehaviour {
    public Button buttonComponent;
    public HorizontalLayoutGroup buttonLayout;

    // Update is called once per frame
    void Update() {
        RectOffset tempPadding = new RectOffset(
        buttonLayout.padding.left,
        buttonLayout.padding.right,
        buttonLayout.padding.top,
        buttonLayout.padding.bottom);
    
       if (buttonComponent.isPressed) { //This does not work OFC!
        tempPadding.bottom = 2;
       } else {
           tempPadding.bottom = 4;
       }     

       buttonLayout.padding = tempPadding;
    }
}

The problem is that I cannot seem to identify when the button enters said pressed state, which seem like a simple enough problem yet I cannot find an answer to it. I've looked all over the internet but couldn't find anything useful.

\$\endgroup\$
5
  • \$\begingroup\$ Is SpriteState.pressedSprite applicable here? (Accessed via Selectable.spriteState) \$\endgroup\$
    – DMGregory
    Commented May 13, 2021 at 13:30
  • \$\begingroup\$ You might be onto something, but by itself it doesn't do anything. I think it might just check if the sprite exists, and since it does, it always gives back true. \$\endgroup\$ Commented May 13, 2021 at 13:46
  • \$\begingroup\$ Are you able to compare that sprite to the one being displayed in the button's image component? \$\endgroup\$
    – DMGregory
    Commented May 13, 2021 at 14:04
  • \$\begingroup\$ Hmm, good idea. I will check later tonight! \$\endgroup\$ Commented May 13, 2021 at 14:18
  • \$\begingroup\$ @DMGregory, I was able to try your idea out, but unfortunately it does not work. The problem is that the value of the button's image property never changes; it always gives back its default sprite for normal state regardless of state change. \$\endgroup\$ Commented May 13, 2021 at 20:30

1 Answer 1

0
\$\begingroup\$

The Guys over at the Unity3D sub-Reddit had come up with a good solution, using the even handler. I have not come up with this answer, and I don't want to take credit for it, but there is no one else to post it here; so, I have to:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class ButtonController : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
public HorizontalLayoutGroup buttonLayout;

public void OnPointerDown (PointerEventData pointerEventData)
{
    RectOffset tempPadding = new RectOffset(
        buttonLayout.padding.left,
        buttonLayout.padding.right,
        buttonLayout.padding.top,
        buttonLayout.padding.bottom);

    tempPadding.bottom = 0;
    buttonLayout.padding = tempPadding;
}

public void OnPointerUp(PointerEventData pointerEventData)
{
    RectOffset tempPadding = new RectOffset(
     buttonLayout.padding.left,
     buttonLayout.padding.right,
     buttonLayout.padding.top,
     buttonLayout.padding.bottom);

    tempPadding.bottom = 4;
    buttonLayout.padding = tempPadding;
}
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .