Organizing images inside panels and changing panel depths via buttons
UI Panels are provided by Unity to allow UI controls to be grouped and moved together, and also to visually group elements with an Image background (if desired). The sibling depth is what determines which UI elements will appear above or below others. We can see the sibling depth explicitly in the Hierarchy, since the top-to-bottom sequence of UI GameObjects in the Hierarchy sets the sibling depth. So, the first item has a depth of 1, the second has a depth of 2, and so on. The UI GameObjects with larger sibling depths (further down the Hierarchy) appear above the UI GameObjects with lower sibling depths.
In this recipe, we'll create three UI panels, each showing a different playing card image. We'll also add four triangle arrangement buttons to change the display order (move to bottom, move to top, move up one, and move down one).
Getting ready
For this recipe, we have prepared the images that you need in a folder named Images
in the 1362_01_08
folder.
How to do it...
To create the UI Panels whose layering can be changed by the user-clicking buttons, follow these steps:
- Create a new Unity 2D project.
- Create a new UI Panel named
Panel-jack-diamonds
. Position it in the middle-center part of the screen, and size it 200 pixels wide by 300 pixels high. Uncheck the Image (Script) component for this panel (since we don't want to see the default semi-transparent rectangular grey background image of a panel). - Create a new UI Image, and child this image to Panel-jack-diamonds.
- Position the Panel-jack-diamonds image at center-middle, and size it to 200 x 300. Drag the Jack-of-diamonds playing card image into the Source Image property, for the Image (Script) component in the Inspector tab.
- Create a UI Button named Button-move-to-front. Child this button to Panel-jack-diamonds. Delete the Text child GameObject of this button (since we'll use an icon to indicate what this button does).
- Size the Button-move-to-front button to 16 x 16, and position it top-center of the player card image, so that it can be seen at the top of the playing card. Drag the
icon_move_to_front
arrangement triangle icon image into the Source Image property, for the Image (Script) component, in the Inspector view. - Ensure that the Button-move-to-front button is selected in the Hierarchy. Then, click on the plus sign (+) at the bottom of the Button (Script) component, in the Inspector view to create a new OnClick event handler for this button.
- Drag Panel-jack-diamonds from the Hierarchy over the Object slot (immediately below the menu saying Runtime Only).
- Now, select the RectTransform.SetAsLastSibling method from the drop-down function list (initially showing No Function).
Note
This means that when the Button receives an OnClick event, the RectTransform of the Panel will be sent the SetAsLastSibling message – this will move the Panel to the bottom of the GameObjects in the Canvas, and therefore will move this Panel in front of all other GameObjects in the Canvas.
- Repeat step 2; create a second Panel with a move-to-front button. Name this second Panel Panel-2-diamonds, then move and position it slightly to the right of Panel-jack-diamonds, allowing both the move-to-front buttons to be seen.
- Save your scene and run the game. You will be able to click the move-to-front button on either of the cards to move that card's panel to the front. If you run the game with the Game panel not maximized, you'll actually see the panels changing order in the list of the children of the Canvas in the Hierarchy.
How it works...
You've created two UI Panels, each panel containing an image of a playing card and a button whose action will make its parent panel move to the front. The button's action illustrates how the OnClick function does not have to be the calling of a public method of a scripted component of an object, but it can be sending a message to one of the components of the targeted GameObject—in this instance we send the SetAsLastSibling message to the RectTransform of the Panel in which the Button is located.
There's more...
There are some details that you don't want to miss.
Moving up or down by just one position, using scripted methods
While the Rect Transform offers a useful SetAsLastSibling (move to front) and SetAsFirstSibling (move to back), and even SetSiblingIndex (if we knew exactly what position in the sequence to type in), there isn't a built-in way to make an element move up or down, just a single position in the sequence of GameObjects in the Hierarchy panel. However, we can write two straightforward methods in C# to do this, and we can add buttons to call these methods, providing full control of the top-to-bottom arrangement of the UI controls on the screen. To implement four buttons (move-to-front/move-to-back/up one/down one), do the following:
- Create a C# script class called
ArrangeActions
, containing the following code, and add an instance as a scripted component to each of your Panels:using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System.Collections; public class ArrangeActions : MonoBehaviour { private RectTransform panelRectTransform; void Start(){ panelRectTransform = GetComponent<RectTransform>(); } public void MoveDownOne(){ print ("(before change) " + GameObject.name + " sibling index = " + panelRectTransform.GetSiblingIndex()); int currentSiblingIndex = panelRectTransform.GetSiblingIndex(); panelRectTransform.SetSiblingIndex( currentSiblingIndex - 1 ); print ("(after change) " + GameObject.name + " sibling index = " + panelRectTransform.GetSiblingIndex()); } public void MoveUpOne(){ print ("(before change) " + GameObject.name + " sibling index = " + panelRectTransform.GetSiblingIndex()); int currentSiblingIndex = panelRectTransform.GetSiblingIndex(); panelRectTransform.SetSiblingIndex( currentSiblingIndex + 1 ); print ("(after change) " + GameObject.name + " sibling index = " + panelRectTransform.GetSiblingIndex()); } }
- Add a second button to each card panel, this time, using the arrangement triangle icon image called
icon_move_to_front
, and set the OnClick event function for these buttons to SetAsFirstSibling. - Add two further buttons to each card panel with the up and down triangle icon images:
icon_down_one
andicon_up_one
. Set the OnClick event handler function for the down-one buttons to call theMoveDownOne()
method, and set the functions for the up-one buttons to call theMoveUpOne()
method. - Copy one of the panels to create a third card (this time showing the Ace of diamonds). Arrange the three cards so that you can see all four buttons for at least two of the cards, even when those cards are at the bottom (see the screenshot at the beginning of this recipe).
- Save the scene and run your game. You will now have full control over the layering of the three card panels.