Search code examples
c#unity-game-enginelayoutgameobject

How to bring a specific child on the front in horizontal layout in Unity


So basically I have a hand with cards. Those cards are gameobject prefab and when I hover one it scale bigger and slightly move upward. But when scaling it overlap the card at his left and stay behind the one at his right, and I want the card to get over the cards instead.

I tried to change the z index and the layer but all cards in hand are ruled by the same horizontal layout...

Should I just push the cards on each side of the hovered one ? Or someone have a solution to draw a specific child in front of the others ?


Solution

  • What you can do is to dynamically add a new Canvas to your object that you want to be in front, and override sorting:

    enter image description here

    In code, you can do something like this:

    var newCanvas = yourGameObject.AddComponent<Canvas>();
    newCanvas.overrideSorting = true;
    newCanvas.sortingOrder = 1; // this has to be higher than order of parent canvas
    

    Of course you should remember to remove this canvas when it's not needed anymore.

    Edit: updated the solution with full code that I verified to be working. What I missed was adding the raycaster to the new canvas. This is the full code:

    public class YourClass : MonoBehaviour, IPointerExitHandler, IPointerEnterHandler
    {
        private Canvas tempCanvas;
        private GraphicRaycaster tempRaycaster;
    
        public void OnPointerEnter(PointerEventData eventData)
        {
            // add and configure necessary components
            tempCanvas = gameObject.AddComponent<Canvas>();
            tempCanvas.overrideSorting = true;
            tempCanvas.sortingOrder = 1;
            tempRaycaster = gameObject.AddComponent<GraphicRaycaster>();
            
            // your operations on the object
            transform.localScale = new Vector2(1.1f, 1.1f);
            // ...
        }
    
        public void OnPointerExit(PointerEventData eventData)
        {
            // remove components that are not needed anymore
            Destroy(tempRaycaster);
            Destroy(tempCanvas);
            
            // your operations on the object
            transform.localScale = new Vector2(1f, 1f);
            // ...
        }
    }