Panel PreFab render order

I have a canvas and I have created a ‘card’ on a Panel. That card has various image and text elements.

The render order of the ‘cards’ is currently based on the order in which the card is brought into the scene.

The Panel has no Sorting Layer on it like a Sprite Image does and even the sprites I use that are in the Image elements have no Sorting Layer option.

How do I get a ‘card’ Panel to have render priority?

Maybe this will make it clearer :slight_smile:

If you are using the new ui elements, everything is rendered in the order they are listed. So
Parent
-child (rendered first)
-child (rendered next)
-child (rendered last)

So whatever is at the bottom is always drawn on top of the others.

If you need to move stuff around, there are a few ways to do it.
First, a canvas does have the option to sort them. But, if you’re just putting stuff under one canvas, your best bet is just to move the order of the children around.

You can use setaslastsibling

So if you want the first child in the list to display on top of the others, you set it as the last sibling and it will now display in front of everything else in that canvas.

1 Like

You Rock Brathnann :smile:

Glad I could help. I had to use this on a project I worked on, so it stood out right away.

Wow… well I’ve tried so many things.

I have this script (which would seem to be the best of my efforts) attached to the child Panel and it is not working

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class SetCardLast : MonoBehaviour {

    private RectTransform MoveToFront;

    void Awake ()
 {
        MoveToFront = GetComponent <RectTransform> (); 
        MoveToFront.SetAsLastSibling ();
    }

  
       
    }

Is your intent to trigger it in awake? I’m not sure how your game is laid out, but if you have this on a “card” object and you have several cards in the game, each one tries to move to front right away and only that one time, after that, you have nothing to trigger it. If you follow the example in the link, it shows you one where they are clicking on the object which will bring it to the front.

You need to figure out how you want to trigger the code and set it up for that.

Ya I have a simple scroll thru 5 Plane objects (using D Pad) and I want to set the LastSibling to which ever is the current choice.

So in the image I provided if I hit D Pad right once the 3rd card would go down and the 4th card will raise up and need to be Last Sibling.

ATM I’m trying to keep it simple and just get the 3rd card to be last sibling but with no luck.

I named the script “SetCardLast” and I was just hoping to be able to invoke it for any card that is the current choice.

This current attempt comes from my attempt to use what I learned from this script example “FocusPanel” (3rd one down):

I have been playing with other versions like this one as well:

So whenever you make the card “rise up” you’ll also need to set it as last sibling at that point. Right now, you’re not doing anything to make it come forward except at the start of the game.

in your code…

if D-Pad right hit once then
NextCard.SetAsLastSibling();

Sounds good but it does not seem to work:

using UnityEngine;
using System.Collections;
using InControl;

public class ShowCard : MonoBehaviour {
    private GameObject hand;
    // Use this for initialization
    void Start () {
      
        hand = GameObject.FindGameObjectWithTag ("ChoiceCard");

    }

    // Update is called once per frame
    void Update () {
        if (InputManager.ActiveDevice.DPadRight.WasPressed)
        {
            hand.gameObject.transform.SetAsLastSibling ();
        }


        if (InputManager.ActiveDevice.DPadLeft.WasPressed)
        {
            hand.gameObject.transform.SetAsFirstSibling ();
        }
    }
}

The error is : MissingReferenceException: The object of type ‘Object’ has been destroyed but you are still trying to access it.

Which is very frustrating as I get that same error trying to Instantiate the “card” PreFab.

I had just been working on the cards in scene but decided to move on getting the cards to Instantiate until I could figure out this SetLast thing.

So now same error with getting cards into scene:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class DrawCard : MonoBehaviour {

    GameObject card = Resources.Load<GameObject>("Assets/Prefabs/HandCard");
    public Transform Deck;
   
    // Use this for initialization
    void Start () {
        GameObject newCard = Instantiate (card, Deck.position, Deck.rotation) as GameObject;
        newCard.name = gameObject.name;
        newCard.transform.parent = gameObject.transform;
    }
  
    // Update is called once per frame
    void Update () {
  
    }
}

I have not coded in a long time and this is just not clicking for me.

One suggestion is you make your GameObject card public and instead of trying to set it = there (which I think doing that actually doesn’t work the way you have it) is to just drop the prefab into the slot in the inspector.

Unless you’re using an older version of unity, should use setparent instead

Make sure Deck is set to something in the inspector.

In your first script, my guess is hand is targeting the wrong thing, or you’re just not updating it’s value. So when it tries to set it as last, it no longer exist.

I know what you’re trying to do, I just don’t understand how you’re trying to do it.

You may need to throw in some print or debug.log statements to make sure your variables are targeting what you think they are suppose to be.

1 Like

That worked… Thank you again Brathnann!
I still need to get the card to instantiate but that needs to be another thread if I can’t figure it :wink: