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:
