본문 바로가기
[Unity]

[Unity] UI 모양을 내 맘대로 바꿔보자(VertexHelper)

by 김기승 2024. 4. 21.

이전에 Mesh를 생성하여 도형을 만들어봤다.

[Unity] Mesh를 생성하여 도형 만들기 (tistory.com)

 

[Unity] Mesh를 생성하여 도형 만들기

3D 게임을 만들기 위해서는 다양한 모델링을 활용한다. 이 모델링들은 Mesh 데이터를 통해 형상화하게 되는데, 유니티에서는 Mesh 클래스를 생성해서 원하는 도형을 만들 수 있다. 이번 글에서는 Me

giseung.tistory.com

 

이와 같은 원리로, UI에도 VertexHelper라는 클래스를 활용하여,

Canvas에서 사용할 수 있는 원하는 형태의 UI를 만들어낼 수 있다.

자세히 알아보도록 하자.


작성 방법

아래의 코드는 Image 컴포넌트 형태인 사각형을 직접 구현한 것이다.

using UnityEngine;
using UnityEngine.UI;

public class SquareImage : Image
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        base.OnPopulateMesh(vh);

        // 기존 정점을 모두 제거한다.
        vh.Clear();

        // 가로와 세로 길이를 저장한다.
        float width = rectTransform.rect.width;
        float height = rectTransform.rect.height;

        // 정점과 UV를 왼쪽 아래부터 시계방향으로 지정한다.
        vh.AddVert(new Vector2(-width * 0.5f, -height * 0.5f), color, new Vector2(0f, 0f));
        vh.AddVert(new Vector2(-width * 0.5f, height * 0.5f), color, new Vector2(0f, 1f));
        vh.AddVert(new Vector2(width * 0.5f, height * 0.5f), color, new Vector2(1f, 1f));
        vh.AddVert(new Vector2(width * 0.5f, -height * 0.5f), color, new Vector2(1f, 0f));

        // 삼각형도 마찬가지로 왼쪽 아래부터 시계방향으로 지정한다.
        vh.AddTriangle(0, 1, 2);
        vh.AddTriangle(2, 3, 0);
    }
}

 

우선, Image 컴포넌트를 상속받는다.

 

핵심은 OnPopulateMesh 함수인데,

UI 요소가 정점을 재생성할 때 실행되는 함수이다.

※ Size, Anchors, Pivot 등이 변경될 때

매개변수로는 VertexHelper 인스턴스를 받는다.

 

위에서는 AddVert 함수로 정점과 UV를,

AddTriangle 함수로 삼각형을 지정했다.

결과는 기본 Image 컴포넌트와 동일하다.


Triangle

using UnityEngine;
using UnityEngine.UI;

public class TriangleImage : Image
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        base.OnPopulateMesh(vh);

        // 기존 정점을 모두 제거한다.
        vh.Clear();

        // 가로와 세로 길이를 저장한다.
        float width = rectTransform.rect.width;
        float height = rectTransform.rect.height;

        // 정점과 UV를 왼쪽 아래부터 시계방향으로 지정한다.
        vh.AddVert(new Vector2(-width * 0.5f, -height * 0.5f), color, new Vector2(0f, 0f));
        vh.AddVert(new Vector2(0f, height * 0.5f), color, new Vector2(0.5f, 1f));
        vh.AddVert(new Vector2(width * 0.5f, -height * 0.5f), color, new Vector2(1f, 0f));

        // 삼각형도 마찬가지로 왼쪽 아래부터 시계방향으로 지정한다.
        vh.AddTriangle(0, 1, 2);
    }
}


Circle

using UnityEngine;
using UnityEngine.UI;

public class CircleImage : Image
{
    private readonly int _segment = 64;

    protected override void OnPopulateMesh(VertexHelper vh)
    {
        base.OnPopulateMesh(vh);

        // 기존 정점을 모두 제거한다.
        vh.Clear();

        // 가로와 세로 길이를 저장한다.
        float width = rectTransform.rect.width;
        float height = rectTransform.rect.height;

        // 시계방향으로 한 바퀴를 돌면서 정점을 추가한다.
        for (int i = 0; i < _segment; ++i)
        {
            float rad = Mathf.PI * 2f * i / _segment;
            float sin = Mathf.Sin(rad);
            float cos = Mathf.Cos(rad);

            Vector2 pos = new Vector2(sin * width * 0.5f, cos * height * 0.5f);
            Vector2 uv = new Vector2((sin + 1f) * 0.5f, (cos + 1f) * 0.5f);
            vh.AddVert(pos, color, uv);
            vh.AddTriangle(i, (i + 1) % _segment, _segment);
        }

        // 중앙 정점을 추가한다.
        vh.AddVert(new Vector2(0f, 0f), color, new Vector2(0.5f, 0.5f));
    }
}


 

위 스크립트들을 사용하는 방법은

Canvas 내에 오브젝트를 생성하여 스크립트를 붙이면 된다.

너무 당연한 소리였나.

 

다음에는 이를 활용한 글을 또 가져오도록 하겠다.

댓글