Texturing a cube; different textures on a face

I'm probably unaware of the proper keywords to search for this, but i know I can't be the first one to ask this:

I want to texture a cube that has the different textures for each of the sides. Can this be done within unity, on a prefab?

Thanks in advance!

The default cube from Unity does not allow that.
But you can make a new cube from 6 quads!

I’ve made it into a prefab for you, which you can find [21794-cube.zip|21794].
With it, you can apply different textures to each side :slight_smile:

Let’s say you have a cube, where each side needs to display a different texture (1-6). In your main script, declare this:

(this is from memory, so bear with me)

public Texture2d[] AllCubeTextures;
public Texture2d TextureAtlas;
public Rect[] AtlasUvs;

Now, when you look at the 2d texture array in the Unity inspector, let’s say starting out you have 6 textures, though eventually you may have dozens.
Tell the array in the inspector that it has 6 elements
assign the appropriate texture to each element in the inspector

  1. your first texture
  2. your second texture,
  3. … and so on to 6 textures

Now, in back in your mainscript…you need to use Texture2d.Packtextures to pack these into one big texture, the TextureAtlas. If I remember correctly, it’s something like this:

AtlasUvs = TextureAtlas.PackTextures(AllCubeTextures);

To generate the cube, just build a mesh “by hand”, check out the examples for creating a procedural mesh. I’m some I or someone else can give more information on this if you need it.

So, let’s say you have a cube, with each face assigned a texture number. We have a cube where the “front” side needs to show texture number 3, maybe it’s a brick texture.

When building the uvs for that cube, you just assign the values from AtlasUvs[3] to the uvs for that face. Sorry if this is not specific enough, I’m not in a position to actually post code for building a cube’s faces with uvs, etc. When you actually tell unity to create the mesh, you tell it to use your TextureAtlas texture. All cubes you build would use this same texture atlas, thus everyone really just shares one material.

I hope this is helpful. I think it’s a better approach than having a material for each side of the cube, unless you need different shaders for each side of the cube or something.

You can use FBX model for that.
Most Unity example projects contain FBX models.

UNITY: Resources (archive.org)

This shader wors pretty good for this

Shader "Custom/CubeSurfaceShader"
{
 Properties {
        _MainTex ("Texture", 2D) = "white" {}
        _Face1 ("Face 1", 2D) = "black" {}
        _Face2 ("Face 2", 2D) = "black" {}
        _Face3 ("Face 3", 2D) = "white" {}
        _Face4 ("Face 4", 2D) = "white" {}
        _Face5 ("Face 5", 2D) = "white" {}   
        _Face6 ("Face 6", 2D) = "white" {}
        _BorderSizeF1 ("Border Size Face 1", Range(0, 0.5)) = 0
        _BorderSizeF2 ("Border Size Face 2", Range(0, 0.5)) = 0
        _BorderSizeF3 ("Border Size Face 3", Range(0, 0.5)) = 0.03
        _BorderSizeF4 ("Border Size Face 4", Range(0, 0.5)) = 0
    }

    SubShader {
        Tags {"RenderType"="Opaque"}
        LOD 100

        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f {
                float2 uv : TEXCOORD0;
                float3 normal : TEXCOORD1;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            sampler2D _Face1;
            sampler2D _Face2;
            sampler2D _Face3;
            sampler2D _Face4;
            sampler2D _Face5;
            sampler2D _Face6;
            float _BorderSizeF1;
            float _BorderSizeF2;
            float _BorderSizeF3;
            float _BorderSizeF4;

            v2f vert (appdata v) {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.normal = v.normal;
                return o;
            }

            float4 _MainTex_ST;

            float4 frag (v2f i) : SV_Target {
                float4 col;
                if(i.normal.z > 0.999) {
                if(i.uv.x > (1.0 - _BorderSizeF1) || i.uv.x < _BorderSizeF1 || i.uv.y > (1.0 - _BorderSizeF1) || i.uv.y < _BorderSizeF1)
                    col = float4(0,0,0,1);
                else
                    col = tex2D(_Face1, i.uv);
            }
            else if(i.normal.z < -0.999) {
                 //flipping face 3 texture so that it is orientated the same as sides 1,2&4
                float2 uv = i.uv; 
                uv.x = 1.0 - uv.x; //flip texture in the X
                uv.y = 1.0 - uv.y; //flip texture in the Y
                if(i.uv.x > (1.0 - _BorderSizeF3) || i.uv.x < _BorderSizeF3 || i.uv.y > (1.0 - _BorderSizeF3) || i.uv.y < _BorderSizeF3)
                    col = float4(0,0,0,1);
                else
                    col = tex2D(_Face3, uv);
            }
            else if(i.normal.x > 0.999) {
                if(i.uv.x > (1.0 - _BorderSizeF2) || i.uv.x < _BorderSizeF2 || i.uv.y > (1.0 - _BorderSizeF2) || i.uv.y < _BorderSizeF2)
                    col = float4(0,0,0,1);
                else
                    col = tex2D(_Face2, i.uv);
            }
            else if(i.normal.x < -0.999) {
                if(i.uv.x > (1.0 - _BorderSizeF4) || i.uv.x < _BorderSizeF4 || i.uv.y > (1.0 - _BorderSizeF4) || i.uv.y < _BorderSizeF4)
                    col = float4(0,0,0,1);
                else
                    col = tex2D(_Face4, i.uv);
            }
            else if(i.normal.y > 0.999) col = tex2D(_Face5, i.uv);
            else if(i.normal.y < -0.999) col = tex2D(_Face6, i.uv);
            else col = tex2D(_MainTex, i.uv);
                
                return col;
            }
        ENDCG
        }
    }
    FallBack "Diffuse"
}