Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Tabstrip buttons or which button is selected.

Discussion in 'UGUI & TextMesh Pro' started by Mmmpies, Sep 20, 2014.

  1. Mmmpies

    Mmmpies

    Joined:
    Feb 19, 2014
    Posts:
    31
    Hi,

    I'm switching from DF GUI and want a menu system like the tabstrips from DF GUI. The buttons I've drawn are two simple ones, one that links a line at either side but appears to be open e.g.
    ___
    _| |_ well that looks awful but you get the idea. The other button looks like this:

    ___
    _!__!_ Again awful but, you know, closed as in not currently selected.

    The problem is the default buttons for the new UI don't have a selected option so all buttons either appear open or closed unless I'm currently hovered over them or actively clicking them.

    I know I can just set an image (instead of a button) and do it all via a script recording which one's currently active and setting the image in that script, if I'm being honest I'm hoping someone's already created one! :¬)

    I've looked over the forums but can't find an example.
     
  2. GibTreaty

    GibTreaty

    Joined:
    Aug 25, 2010
    Posts:
    792
    If you're talking about something like this...
    https://dl.dropboxusercontent.com/u/17783172/4.6 Beta Menu/4.6 Beta Menu.html
    ...then I can try to help you out.

    What I've done is use Toggles instead of Buttons and have removed the checkmark. Each Toggle is connected to the same Toggle Group and each "page" that it opens up is a separate GameObject elsewhere in the Canvas. The Toggles each have the desired GameObject's SetActive event set to fire in the Toggle's OnValueChanged event.
     
    Mmmpies likes this.
  3. SubBassman

    SubBassman

    Joined:
    Mar 28, 2011
    Posts:
    16
    Buttons should definitely have a focused state. Any devs around?
     
    rakkarage likes this.
  4. Mmmpies

    Mmmpies

    Joined:
    Feb 19, 2014
    Posts:
    31
    Thanks GibTreaty,

    That is pretty much what I was after but I decided to bite the bullet and try creating one based on the image idea I had.

    Amazed at how easy it was with the new UI event system.

    Basically just setup four images at the top of the UI and four panels then assigned the various images and panels.

    Always like it when the community offers help though so thanks again.
     
    melkior and GibTreaty like this.
  5. Mmmpies

    Mmmpies

    Joined:
    Feb 19, 2014
    Posts:
    31
    And this is the script I attached to each button.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4.  
    5. public class MenuButtonEvents : MonoBehaviour {
    6.  
    7.     public Image MyImage;
    8.     public Text MyText;
    9.     public GameObject MyPanel;
    10.     public Sprite OpenImg;
    11.     public Sprite ClosedImg;
    12.  
    13.     public void OnEnterHover()
    14.     {
    15.         MyText.color = Color.yellow;
    16.     }
    17.  
    18.     public void OnExitHover()
    19.     {
    20.         MyText.color = Color.black;
    21.     }
    22.  
    23.     public void OnClick()
    24.     {
    25.         Messenger.Broadcast ("ButtonChanged");
    26.         MyPanel.SetActive(true);
    27.         MyImage.sprite = OpenImg;
    28.  
    29.     }
    30.  
    31.     public void ButtonChanged()
    32.     {
    33.         MyImage.sprite = ClosedImg;
    34.         MyPanel.SetActive(false);
    35.     }
    36.  
    37.     public void OnEnable()
    38.     {
    39.         Messenger.AddListener("ButtonChanged", ButtonChanged);
    40.     }
    41.  
    42.     public void OnDisable()
    43.     {
    44.         Messenger.RemoveListener("ButtonChanged", ButtonChanged);
    45.     }
    46. }
    Everything's set to public whilst testing it but if you use the same images all the time for open and closed they could be set to private and referenced in the script.

    The text is just a child of the button, Spells, Inventory etc.

    Then I added Event Triggers for...
    Pointer Enter = OnEnterHover
    Pointer Exit = OnExitHover
    Pointer Click = OnClick

    For anyone learning the new UI add the event trigger component, then Add New. Drag the relevant button onto Object area that appears. Because the script has already been dragged onto the button all functions in the script can be accessed by the function button that appears.

    Got to say I'm starting to really like the new UI.
     
    melkior likes this.
  6. Mmmpies

    Mmmpies

    Joined:
    Feb 19, 2014
    Posts:
    31
    And this is the end result:
     

    Attached Files:

  7. Mmmpies

    Mmmpies

    Joined:
    Feb 19, 2014
    Posts:
    31
    Thanks SubBassman,

    I think they can have focus but if it treats focus the same DF GUI that hits issues as well.

    For example if I have an inventory tab then I'm going to want to have an equip item button next to each item. If I select that then focus is lost from the tab button. At least that's the issue I had when I used DF GUI and it makes sense that it'd work that way in this UI as well because only one thing can have focus at a time. What it really needs is a separate button state to say it's still the selected tab.

    Happily the new UI is so easy to work extra events into the image solution I worked out that it's working better than the UI was in DF GUI, which is saying something because Daikon was/is great.

    So for any devs I don't think this is an issue.

    Incidentally I also came across this if my solution doesn't fit the needs of any projects out there.

    https://github.com/AyARL/UnityGUIExamples/tree/master/Tabs/Assets

    Although, as normal, I only found that after creating my own!
     
  8. melkior

    melkior

    Joined:
    Jul 20, 2013
    Posts:
    199

    So I'm definitely still learning the new UI. When I attempt to follow your instructions to test out this tab idea I get an error that "The name 'Messenger' does not exist in the current context'.

    I thought this might be a MessageSystem component so added that but it doesn't contain a definition for Broadcast so that's not it? Any suggestions? Thanks!
     
  9. melkior

    melkior

    Joined:
    Jul 20, 2013
    Posts:
    199
    The only problem with that repo is its under GNU license

     
  10. Mmmpies

    Mmmpies

    Joined:
    Feb 19, 2014
    Posts:
    31
    Sorry Melkior I always forget which bits are built in and which bits are the added functionality I use after following burgzerg tutorials.



    Follow that and you should be fine after adding the extension, you could also reference what to set as active in different ways (not everyone likes broadcasting messages - never had an issue with it myself though).

    Feel free to use my script without any license!

    Good luck.
     
  11. Mmmpies

    Mmmpies

    Joined:
    Feb 19, 2014
    Posts:
    31
    PS you only need to add the CsharpMessenger scripts not anything else.
     
  12. melkior

    melkior

    Joined:
    Jul 20, 2013
    Posts:
    199
    Excellent I'll check that out , thanks!

    I have a solution had started on that doesn't involve sending messages ; (I wasn't for or against messages by the way) but I was curious more how other people are approaching it.

    Mine I just barely started and is pretty hard coded/hacky so I knew there had to be better ways about it :) Thanks again for the tips/scripts/videos!
     
  13. Mmmpies

    Mmmpies

    Joined:
    Feb 19, 2014
    Posts:
    31
    Thought I'd update this as I hit a load of problems with the panel becoming disabled and then the listeners not responding.

    Turns out I just didn't know enough about the new GUI as a better way of handling this is with CanvasGroups.

    Add a canvas group on each tabs base panel and one on the main menu panel. When you click on the open menu button you need to make the alpha = 1, BlockRaycast = True and Interactable = True for the main menu and whichever tab you want to start on. You can leave the tab panel like this as it'll still go invisible when the Main Menu is exited as long as your not ignoring parent groups.

    Then in the ButtonChanged() Function tell it to change the alpha etc instead of disabling and enabling the panel. What I did was write a PanelVis Script that also gets attached to each panel you want to interact with.

    That picks up CanvasGroup from the parent it's attached to:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4.  
    5. public class PanelVis : MonoBehaviour {
    6.    
    7.     private CanvasGroup cgroup;
    8.  
    9.     void Start()
    10.     {
    11.         cgroup = transform.GetComponent<CanvasGroup> ();
    12.     }
    13.  
    14.     public void ShowMe()
    15.     {
    16.         cgroup.alpha = 1f;
    17.         cgroup.blocksRaycasts = true;
    18.         cgroup.interactable = true;
    19.     }
    20.  
    21.     public void HideMe()
    22.     {
    23.         cgroup.alpha = 0f;
    24.         cgroup.blocksRaycasts = false;
    25.         cgroup.interactable = false;
    26.     }
    27. }
    Then in my original script we need to see the panelVis so:

    private PanelVis MyPanelVis;

    In Start or Awake have this:

    MyPanelVis = MyPanel.GetComponent<PanelVis>();

    Then just call the ShowMe() or HideMe() instead of the MyPanel.SetActive(true); or MyPanel.SetActive(false);