Dragged objects do not display at correct depth.

Lectori Salutem,

I’m prototyping a simple game. There’s a table and on that table can be three piles of playing cards.You start with a pile of 9 cards in the middle and have to move the cards to either the left or right of the middle pile. All is done in top view.
Since I’ve had bad experiences with the Rigidbody and Collisionboxes (cards too thin?), I decided to program the display myself. Initially, the Y-position of the table is at 0, each subsequent card on the pile at 0.5 above it with a box thickness of 0.2 You won’t notice the gap since it’s top view.
The initial pile in the middle is generated correctly. All cards are there with the correct Y-value in the inspector. As soon as I pick up a card (click on it), I move the Y-position to 10 so you see a lift. But moving it left or right, it sometimes ‘disappears’ in to the piles as if it’s behind other cards although the inspector shows Y=10 for the card I’m dragging and values less than 4 for the cards on the piles.
Then when I drop the card on one of the piles, the inspector shows the correct Y value (I count the number of cards in the pile and set the Y value to that count + 0.5. But the card sometimes disappears behind other cards on the pile instead.

What am I doing wrong? It all seems so simple and straightforward but I can’t get it to work.

For completeness, here’s the script to move the cards (attached to each card).:

using UnityEngine;
public class CardBehaviour : MonoBehaviour
{
    Vector3 offset;
  
    void Start()
    {
        float angle = Random.Range(-10, 10);
        transform.RotateAround(transform.position, transform.up, angle);
    }
    void OnMouseDown()
    {
        offset = transform.position - MouseWorldPosition();
    }
    void OnMouseDrag()
    {
        transform.position = new Vector3(MouseWorldPosition().x + offset.x, 10f, MouseWorldPosition().z + offset.z);
    }
    Vector3 MouseWorldPosition()
    {
        var mouseScreenPos = Input.mousePosition;
        mouseScreenPos.z = Camera.main.WorldToScreenPoint(transform.position).z;
        return Camera.main.ScreenToWorldPoint(mouseScreenPos);
    }
}

Any suggestions appreciated.
Thanks for your time.

Leon

Three (3) ways that Unity draws / stacks / sorts / layers / overlays stuff:

In short,

  1. The default 3D Renderers draw stuff according to Z depth - distance from camera.

  2. SpriteRenderers draw according to their Sorting Layer and Sorting Depth properties

  3. UI Canvas Renderers draw in linear transform sequence, like a stack of papers

If you find that you need to mix and match items using these different ways of rendering, and have them appear in ways they are not initially designed for, you need to:

  • identify what you are using
  • search online for the combination of things you are doing and how to to achieve what you want.

There may be more than one solution to try.

Additional reading in the official docs:

And SortingGroups can also be extremely helpful in certain circumstances:

Thanks. I already figured I’d go back to basics. Since I don’t really need 3D (I can simulate the lift) I’m now looking into 2D. I thought it would be easier than that but alas… lesson learned (and learning) Again, thanks for the links. .