Search Unity

Image Swap Behavior

Discussion in '2D' started by drumminhands, Apr 16, 2021.

  1. drumminhands

    drumminhands

    Joined:
    Apr 4, 2020
    Posts:
    9
    Hello. I must be missing something simple. Always the way, right. I have a gameobject on screen that is a button. It initializes with an image of a play button (triangle). When you click it, it plays sound, and switches the sprite to a pause button (two vertical lines). When the user clicks it again, it will stop the music and change it's image back to a play button.

    Right now I have code that works fine if you click the button. But, if you hit the play button, it starts playing music and swaps to the pause sprite, if I then click anywhere else on the screen, the sprite goes back to a play button. I don't want that image swap to happen unless I click the button itself. How do I make that happen?

    Attached is an image of the inspector. You can see a screenshot video of the experience here: https://drive.google.com/file/d/1xIqg6SfBFwlGrAk2RZk264rzL4YZ0lry/view?usp=sharing

    And below is my code.

    Thanks for the advice.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. public class PlayPauseBtn : MonoBehaviour
    5. {
    6.     bool activated;
    7.     [SerializeField] private Sprite toPlayImg;
    8.     [SerializeField] private Sprite toPlayImgHover;
    9.     [SerializeField] private Sprite toPauseImg;
    10.     [SerializeField] private Sprite toPauseImgHover;
    11.     GameObject am; // reference to audio manager
    12.     GameObject btn; // reference to play/pause button
    13.  
    14.     private void Start()
    15.     {
    16.         activated = true; // initialize
    17.         am = GameObject.Find("AudioManager");
    18.         btn = GameObject.Find("PlayBtn");
    19.     }
    20.  
    21.     public void Toggle()
    22.     {
    23.         if (activated)
    24.         {
    25.             activated = false;
    26.             am.GetComponent<AudioManager>().Play("preview"); // play sound
    27.  
    28.             // show pause button
    29.             SpriteState ss = new SpriteState();
    30.             ss.selectedSprite = toPauseImg;
    31.             ss.pressedSprite = toPauseImgHover;
    32.             ss.highlightedSprite = toPauseImg;
    33.             ss.disabledSprite = toPauseImg;
    34.             btn.GetComponent<Button>().spriteState = ss;
    35.  
    36.         }
    37.         else
    38.         {
    39.             activated = true;
    40.             am.GetComponent<AudioManager>().Stop("preview"); // stop sound
    41.  
    42.             // show play button
    43.             SpriteState ss = new SpriteState();
    44.             ss.selectedSprite = toPlayImg;
    45.             ss.pressedSprite = toPlayImgHover;
    46.             ss.highlightedSprite = toPlayImg;
    47.             ss.disabledSprite = toPlayImg;
    48.             btn.GetComponent<Button>().spriteState = ss;
    49.  
    50.         }
    51.     }
    52. }
    53.  
     

    Attached Files:

  2. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,466
    Where are all the places you are calling the Toggle() function? I imagine it is on the Play/Pause button but is there anywhere else?
     
  3. drumminhands

    drumminhands

    Joined:
    Apr 4, 2020
    Posts:
    9
    If you look at the attached .png, you can see I call it OnClick() for the Play/Pause button. That's the only place. In my code if I change "public void Toggle()" to "void OnMouseUp()" it results in the same behavior. So no fix there. What's next to look at?
     
  4. drumminhands

    drumminhands

    Joined:
    Apr 4, 2020
    Posts:
    9
    I made a study of just the button behavior. Same issues. Once you hit the button once, it moves to the pause sprite. Then if you click anywhere on the screen (not the button), the sprite turns back into a play sprite. I don't want that. Any help? Download the whole project here.
     

    Attached Files:

  5. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,466
    So i dont have the same Unity version as your project and i dont really want a 5th one on my computer lol so i cant test out the project you sent. Lets try to debug this then:

    When you click the Play button and it turns into the Pause button, what does the inspector of the Pause button look like? You sent a screenshot of the Play button but i want to see what the Pause one looks like. Also, why is there a box collider2d? Was that for testing the OnMouseUp behaviour? Also, do you have the button bounds set up properly for the Pause button? Aka, those 4 little mouse pointer things on each corner of the button object (note the may be like an X if they are all bunched to the middle, but for your case they may be as wide as the entire canvas).

    Try checking those and see if that points you to the issue.
     
  6. drumminhands

    drumminhands

    Joined:
    Apr 4, 2020
    Posts:
    9
  7. drumminhands

    drumminhands

    Joined:
    Apr 4, 2020
    Posts:
    9
    The mouse bounds for the button are the entire button object. You can see it in the video.

    Thanks again for helping me with this. It should really be a simply thing. I don't know why it's so hard. Is there a different way to make the button work? Attached are my sprites in case you want to try one in your version of unity from scratch. pause_btn.png pause_btn_down.png play_btn.png play_btn_down.png
     
  8. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,466
    Ill give it a go this afternoon. Here are some tutorials in the meantime: upload_2021-4-19_12-14-23.png

    Also, you could look into using an EventTrigger component. But i think the button should be just fine.
     
  9. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    Hi @drumminhands

    IIRC, when you click outside of button, it will default to its standard look, so selected state is no longer true. You can test this by setting default buttons "Selected Color" to yellow or something like that, and then press Play. If you first click a button and then click outside of button's click area, it will revert back to normal color/sprite from its selected color/sprite.

    But I have no idea why it changes your struct back to the one you start with, you'll probably find out by reading Selectable / Button's code...

    An idea... maybe Toggle UI element could be used instead of Button?

    For these reasons, I have simply created my own primitive toggle buttons and moved on. See
    IPointerEnterHandler, IPointerExitHandler and IPointerClickHandler interfaces, it is pretty easy.

    BTW - you should ask this question in UI forum instead, this is not a 2D question. You'll probably get better answers there.
     
    Last edited: Apr 19, 2021