Creating a 9-Sliced 3D Plane Mesh Without a Filled Center

I was wondering if anyone knew how to create a 3D mesh plane in Unity that doesn’t not have a filled center, much like the UI Image component that doesn’t have a center, but edges only?

Use a 3D program (like Blender3D) and make the geometry you want.

If you insist on doing it with Unity3D primitives, you could probably combine a handful of primitives, scaling and stretching them how you need to, to get the effect you want.

I was hoping to have more dynamic control over it than a 3D modeling package can provide. The primitive approach is probably the route to go, but I was hoping someone might have come up with a more efficient solution, such as creating a mesh at run-time and removing the filled-center.

Also, take a look-see at Prototype in the asset store. Methinks it could do what you need. It’s free last I checked, part of a larger ProCore package that is for-pay.

For anyone with a similar question, the answer at the bottom did exactly what I wanted. I wanted a 9-sliced plane mesh. If you want to remove the center filled plane comment out the lines that I did. I’m posting my modified code to help others.

using UnityEngine;

[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
public class SlicedMesh : MonoBehaviour
{
    [SerializeField]
    private float borderThickness = 1.0f, width = 3.0f, height = 3.0f, marginUV = 1.0f;

    [SerializeField]
    private bool updateInRealTime = false;

    private Mesh mesh = null;

    private float _b = 0.1f;
    public float Border
    {
        get
        {
            return _b;
        }
        set
        {
            _b = value;
            CreateSlicedMesh();
        }
    }

    private float _w = 1.0f;
    public float Width
    {
        get
        {
            return _w;
        }
        set
        {
            _w = value;
            CreateSlicedMesh();
        }
    }

    private float _h = 1.0f;
    public float Height
    {
        get
        {
            return _h;
        }
        set
        {
            _h = value;
            CreateSlicedMesh();
        }
    }

    private float _m = 0.4f;
    public float Margin
    {
        get
        {
            return _m;
        }
        set
        {
            _m = value;
            CreateSlicedMesh();
        }
    }

    private void Start()
    {
        Width = width;
        Height = height;
        Border = borderThickness;
        Margin = marginUV;
        CreateSlicedMesh();
    }

    private void LateUpdate()
    {
        if (updateInRealTime)
            RealTimeMeshUpdate();
    }

    private void RealTimeMeshUpdate()
    {
        if (width != Width)
            Width = width;
        if (height != Height)
            Height = height;
        if (borderThickness != Border)
            Border = borderThickness;
        if (marginUV != Margin)
            Margin = marginUV;
    }

    private void CreateSlicedMesh()
    {
        if(mesh == null)
        {
            mesh = new Mesh();
            GetComponent<MeshFilter>().mesh = mesh;
        }
        mesh.vertices = new Vector3[] {
        new Vector3(0, 0, 0), new Vector3(_b, 0, 0), new Vector3(_w-_b, 0, 0), new Vector3(_w, 0, 0),
        new Vector3(0, _b, 0), new Vector3(_b, _b, 0), new Vector3(_w-_b, _b, 0), new Vector3(_w, _b, 0),
        new Vector3(0, _h-_b, 0), new Vector3(_b, _h-_b, 0), new Vector3(_w-_b, _h-_b, 0), new Vector3(_w, _h-_b, 0),
        new Vector3(0, _h, 0), new Vector3(_b, _h, 0), new Vector3(_w-_b, _h, 0), new Vector3(_w, _h, 0)
        };

        mesh.uv = new Vector2[] {
        new Vector2(0, 0), new Vector2(_m, 0), new Vector2(1-_m, 0), new Vector2(1, 0),
        new Vector2(0, _m), new Vector2(_m, _m), new Vector2(1-_m, _m), new Vector2(1, _m),
        new Vector2(0, 1-_m), new Vector2(_m, 1-_m), new Vector2(1-_m, 1-_m), new Vector2(1, 1-_m),
        new Vector2(0, 1), new Vector2(_m, 1), new Vector2(1-_m, 1), new Vector2(1, 1)
        };

        mesh.triangles = new int[] {
        0, 4, 5,
        0, 5, 1,
        1, 5, 6,
        1, 6, 2,
        2, 6, 7,
        2, 7, 3,
        4, 8, 9,
        4, 9, 5, 
        //Comment Out these lines to Remove the center plane,
        //Or comment them in to add it back in.
        //5, 9, 10,
        //5, 10, 6,
        6, 10, 11,
        6, 11, 7,
        8, 12, 13,
        8, 13, 9,
        9, 13, 14,
        9, 14, 10,
        10, 14, 15,
        10, 15, 11
        };
    }
}

In case someone else is looking for the same 9 sliced plane but with tiled borders, I adjusted the above code a little:

using UnityEngine;

public class SlicedMesh : MonoBehaviour
{
    public bool drawCenterPart = false;
    public int numberOfBorderTiles = 4;
    public float border = 0.1f;
    public float width = 1.0f;
    public float height = 1.0f;
    public float margin = 0.4f;


    void Start()
    {
        CreateSlicedMesh();
    }

    public void CreateSlicedMesh()
    {
        Debug.Assert(numberOfBorderTiles >= 3, "This code does not work with less then 3 repeated border tiles!");

        int numVertices = (numberOfBorderTiles - 1) * 8 + 16;

        float b = border;
        float w = width;
        float h = height;
        float m = margin;
        int n = numberOfBorderTiles;
        float dw = (w - (2 * b)) / n; //width of one tile
        float dh = (h - (2 * b)) / n; //height of one tile

        //VERTICES & UV COORDS
        Vector3[] vt = new Vector3[numVertices];
        Vector2[] uv = new Vector2[numVertices];

        //bottom corner tiles
        vt[0] = new Vector3(0, 0); vt[1] = new Vector3(b, 0); vt[n+1] = new Vector3(w - b, 0); vt[n+2] = new Vector3(w, 0);
        uv[0] = new Vector2(0, 0); uv[1] = new Vector2(m, 0); uv[n+1] = new Vector2(1 - m, 0); uv[n+2] = new Vector2(1, 0);
        vt[n+3] = new Vector3(0, b); vt[n+4] = new Vector3(b, b); vt[2*n+4] = new Vector3(w - b, b); vt[2*n+5] = new Vector3(w, b);
        uv[n+3] = new Vector2(0, m); uv[n+4] = new Vector2(m, m); uv[2*n+4] = new Vector2(1 - m, m); uv[2*n+5] = new Vector2(1, m);

        //bottom center tiles
        float u;
        for (int i = 1; i < n; i++)
        {
            u = (i%2 == 1) ? 1-m : m;
            vt[1+i] = new Vector3(i*dw + b, 0);
            uv[1+i] = new Vector2(u, 0);
            vt[n+4+i] = new Vector3(i * dw + b, b);
            uv[n+4+i] = new Vector2(u, m);
        }

        //center left and right columns
        float y;
        float v;
        int tile;
        for (int i = 0; i < n-1; i++)
        {
            v = (i%2 == 0) ? 1-m : m;
            tile = ((n - 1) * 2) + 8 + (i * 4);
            y = (i + 1) * dh + b;
            vt[tile] = new Vector3(0, y);
            uv[tile] = new Vector2(0, v);
            vt[tile + 1] = new Vector3(b, y);
            uv[tile + 1] = new Vector2(m, v);
            vt[tile + 2] = new Vector3(w - b, y);
            uv[tile + 2] = new Vector2(1 - m, v);
            vt[tile + 3] = new Vector3(w, y);
            uv[tile + 3] = new Vector2(1, v);
        }

        tile = ((n - 1) * 6) + 8;

        //top left corner tiles
        vt[tile] = new Vector3(0, h-b); vt[tile+1] = new Vector3(b, h-b); vt[tile+n+1] = new Vector3(w-b, h-b); vt[tile+n+2] = new Vector3(w, h-b);
        uv[tile] = new Vector2(0, 1 - m); uv[tile+1] = new Vector2(m, 1 - m); uv[tile+n+1] = new Vector2(1 - m, 1 - m); uv[tile+n+2] = new Vector2(1, 1 - m);
        vt[tile+n+3] = new Vector3(0, h); vt[tile+n+4] = new Vector3(b, h); vt[tile+(2*n)+4] = new Vector3(w - b, h); vt[tile+(2*n)+5] = new Vector3(w, h);
        uv[tile+n+3] = new Vector2(0, 1); uv[tile+n+4] = new Vector2(m, 1); uv[tile+(2*n)+4] = new Vector2(1 - m, 1); uv[tile+(2*n) + 5] = new Vector2(1, 1);

        //top center tiles
        for (int i = 1; i < n; i++)
        {
            u = (i % 2 == 1) ? 1-m : m;
            vt[tile + 1 + i] = new Vector3(i * dw + b, h-b);
            uv[tile + 1 + i] = new Vector2(u, 1-m);
            vt[tile + n + 4 + i] = new Vector3(i * dw + b, h);
            uv[tile + n + 4 + i] = new Vector2(u, 1);
        }


        //TRIANGLES
        int numTriangles = (numberOfBorderTiles+1) * 24;
        if (drawCenterPart) numTriangles += 6;
        int[] tr = new int[numTriangles];

        //bottom row
        int tri = 0;
        for (int i = 0; i < numberOfBorderTiles + 2; i++)
        {
            tr[tri++] = i;
            tr[tri++] = n+3+i;
            tr[tri++] = n+3+i+1;
            tr[tri++] = i;
            tr[tri++] = n+3+i+1;
            tr[tri++] = i+1;
        }

        //center left and right columns (first row)
        tr[tri++] = n + 3;
        tr[tri++] = (n + 3)*2;
        tr[tri++] = (n + 3)*2+1;
        tr[tri++] = n + 3;
        tr[tri++] = (n + 3)*2+1;
        tr[tri++] = n + 4;

        tr[tri++] = n*2 + 4;
        tr[tri++] = n*2 + 8;
        tr[tri++] = n*2 + 9;
        tr[tri++] = n*2 + 4;
        tr[tri++] = n*2 + 9;
        tr[tri++] = n*2 + 5;

        //center left and right columns (not the first and last row)
        int p;
        for (int i = 0; i < numberOfBorderTiles - 2; i++)
        {
            p = (n + 3) * 2 + (i * 4);
            tr[tri++] = p;
            tr[tri++] = p+4;
            tr[tri++] = p+5;
            tr[tri++] = p;
            tr[tri++] = p+5;
            tr[tri++] = p+1;

            p += 2;
            tr[tri++] = p;
            tr[tri++] = p + 4;
            tr[tri++] = p + 5;
            tr[tri++] = p;
            tr[tri++] = p + 5;
            tr[tri++] = p + 1;
        }

        //center left and right columns (last row)
        p = ((n+3) * 2) + ((n-2) * 4);
        tr[tri++] = p;
        tr[tri++] = p + 4;
        tr[tri++] = p + 5;
        tr[tri++] = p;
        tr[tri++] = p + 5;
        tr[tri++] = p + 1;

        p += 2;
        tr[tri++] = p;
        tr[tri++] = p + n + 3;
        tr[tri++] = p + n + 4;
        tr[tri++] = p;
        tr[tri++] = p + n + 4;
        tr[tri++] = p + 1;

        //top row
        p = (n - 1) * 6 + 8;
        for (int i = 0; i < numberOfBorderTiles + 2; i++)
        {
            tr[tri++] = i + p;
            tr[tri++] = n + 3 + i + p;
            tr[tri++] = n + 3 + i + 1 + p;
            tr[tri++] = i + p;
            tr[tri++] = n + 3 + i + 1 + p;
            tr[tri++] = i + 1 + p;
        }

        if (drawCenterPart)
        {
            tr[tri++] = n + 4;
            tr[tri++] = (n - 1) * 6 + 9;
            tr[tri++] = n*6 + 10;

            tr[tri++] = n + 4;
            tr[tri++] = n*6 + 10;
            tr[tri++] = n*2 + 4;
        }

        Mesh mesh = new Mesh();
        GetComponent<MeshFilter>().mesh = mesh;

        mesh.vertices = vt;
        mesh.uv = uv;
        mesh.triangles = tr;
    }
}

Results in something like this:

Using this as a source: