Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use " 9-sliced" image type in non-GUI elements?

In my game, I am using simple textures on quads. I could see Unity GUI allows us to slice the image by setting "image type" option as sliced.

I would like to do the same to my other textures I use in quads.

In simple words, I dont want the edges of my textures to be scaled when the texture itself is scaled.

Thanks.

like image 775
Distraction Arrestor Avatar asked Feb 14 '15 13:02

Distraction Arrestor


2 Answers

Looks like you have to generate the mesh yourself, not so hard as it sounds. The mesh has to look like this:

9 slice on a quad

Each textured mesh is defined by vertices (red dots on the picture) and (in this case) each vertex has two parameters:

  1. A Vector3 with position. Only x and y used here, as a quad is flat (so, z = 0).
  2. A Vector2 with the UV, that is how the material is put on the mesh. This are the texture coordinates: u and v.

To configure this mesh, I added parameters:

b - for border - how big is the border of the gameobject (in 3d units)
w, h - for width and height of the gameobject (in 3d units)
m - how big is the margin in the image (in float 0f to 0.5f)

How to do this in Unity3d:

  1. Create an GameObject, add a MeshRenderer with the material you want and an empty MeshFilter.
  2. Add a script that creates a mesh. Look at Unity3d docs for Mesh, first example.

Note that for unity3d you have to create this with triangles, not quads (so for each quad make two triangles).

like image 155
Krzysztof Bociurko Avatar answered Nov 15 '22 08:11

Krzysztof Bociurko


Chanibal's solutions worked like a charm for me, but since I wasn't an expert in the matter, it wasn't trivial to me to implement this. I will let this code here in case somebody could find it useful.

using UnityEngine;

public class SlicedMesh : MonoBehaviour
{
    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();
        }
    }

    void Start() 
    {

        CreateSlicedMesh();
    }

    void CreateSlicedMesh()
    {
        Mesh 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, 
            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
        };
    }
}
like image 25
Aernarion Avatar answered Nov 15 '22 08:11

Aernarion