I am busy with a pet project where I am trying to create a Collectible Card Game in 3D.

These cards have Hp and Damage etc. but I cannot find a way to neatly display these values. I tried to use a TextMesh, but all the text just blends into each other if the cards happen to overlap (eg. when the cards are in the hand).

Currently, I am using a plane for each value, and then changing the Material used on that plane, to match the value (eg. a '3' Material if the Damage is 3). It works, but I can't help to think that there has to be a better way.

Is there a way to dynamically display values on a plane so that it looks like the value is a part of the card itself, without changing the materials every time a change occurs? Or suggest anything else that would suit my needs?

If I am taking a horrible approach, you're welcome to nudge me in a better direction.

Thanks in advance

  • \$\begingroup\$ Can you add an example image of how the text is being displayed in relation to the card? \$\endgroup\$ Commented Apr 6, 2016 at 18:24
  • \$\begingroup\$ Do you really need things to be dynamic? As far as I know, usually in such games cards cannot change their values during the game anyway. \$\endgroup\$ Commented Apr 10, 2016 at 18:04
  • \$\begingroup\$ No, it's quite routine for cards to change their values during play. HP obviously goes down when they take damage, plus their attack score goes up and down from other cards powering it up/weakening it, etc. \$\endgroup\$
    – jhocking
    Commented Sep 23, 2016 at 0:35
  • \$\begingroup\$ Can we see a picture of your scene, in order to get an idea of what the issue could be? \$\endgroup\$ Commented Jan 22, 2021 at 17:35

3 Answers 3


Cards in a collectible card game usually have a standardized layout with several images and text labels. That means they are pretty much a UI widget. So you can create each card as a separate UI canvas with the "World Space" rendering mode.

A world space canvas basically behaves like a sprite. You control its position, size and rotation in 3d space using its transform. You can control the draw order of multiple canvases in your scene by:

  • Sorting Layer
  • Order In Layer
  • Distance from camera

(by that priority)

  • 1
    \$\begingroup\$ I've successfully implemented a card game using this world space canvas approach, and can confirm it works well. \$\endgroup\$
    – DMGregory
    Commented Aug 16, 2021 at 16:23

I don't know if this will less costly, but using the Profiler you can find out yourself. You could attach a UICanvas on your card object. On this Canvas, place Text Components in the correct positions.


TextMesh is the way to go with what you are looking for, as you are displaying these cards in a plane. This component wouldn't be a valid choice with non flat surfaces.

Add an empty gameobject to your card as a child and then add TextMesh as a component -> Add Component / Mesh / TextMesh. Put the text you need and, after that, you have to adjust the text to where you want it, do it moving the position of the gameObject. Notice that if the father objects aren't with a 1-1-1 Scale, the text will be deformed, if thats the case you'll need to change your object organization and move the text by script instead using it as a child.

If you rotate the card, you'll notice that the text overlaps above every mesh in the scene, even your own card. To avoid this you need to use a custom shader for the "TextMesh" that will make it render like any other object in the scene.

This is the shader:

Shader "Text/TextNonOverlap Shader" { 
    Properties {
        _MainTex ("Font Texture", 2D) = "white" {}
        _Color ("Text Color", Color) = (1,1,1,1)

    SubShader {
        Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
        Lighting Off Cull Off ZWrite Off Fog { Mode Off }
        Blend SrcAlpha OneMinusSrcAlpha
        Pass {
            Color [_Color]
            SetTexture [_MainTex] {
                combine primary, texture * primary

To use the shader, you need a font in your project, anyone will work. Create a material and put this shader on it, then pick the font you chose and assign it's "Font Texture" in the same field "Font Texture" of the material, this is important.

Then, in the gameobject with the TextMesh, change the font to the one you selected, the same as the one you put it's Font Texture on the material or it won't work. Select in the component MeshRenderer "Materials -> Element 0" and put the material you just created on it, now you have a text that won't overlap, to change it's color just change the color of the material.

It's not complicated but it's easy to mesh up, so be careful.

P.S: Yeah, the text can go outside the card but, as you can see, even hearthstone used a similar approach

enter image description here

  • \$\begingroup\$ Btw, just remembered, if you use this approach you need to be aware that you will need to adjust your shaders to avoid the text overlapping above everything else, more info here: wiki.unity3d.com/index.php?title=3DText \$\endgroup\$
    – Leucaruth
    Commented Sep 23, 2016 at 3:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .