Unity UI에 선 그리기.

안또니오·2023년 11월 13일
0

유니티

목록 보기
5/6

Unity에는 LineRenderer라는 컴포넌트가 있다.

각 지점들을 연결해서 선을 그어주는 유용한 컴포넌트인데,

조건이 있다.

3D 공간이어야한다는 것.

UI 캔버스에서는 따로 Canvas모드를 바꿔주거나 하는 방식으로 표현할 수는 있으나
UI의 RectTransform과 3D Object의 Transform을 맞춰주는 것이 여간 까다로운 것이 아니다.

그래서 UI에서 비슷한 기능을 만들어볼 수 있을 것 같은데....
하며 검색해서 찾은 영상이 있다.

Youtube링크

위 영상의 논지는 컴퓨터 그래픽에서 뭔가 보여낼 때는 삼각형을 이용하고, 그 삼각형을 조합하여 그림을 그려낸다.

그러니 삼각형 지점을 지정해주고, 삼각형을 만들어 그림을 그리자.

전체적인 코드는 아래와 같은데,

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class BezierCurve : Graphic
{
    public List<Vector3> vectors;
    [Range(0.5f, 500f)]
    public float thickness= 1f;
    private Vector3 initVec;
    protected override void OnPopulateMesh(VertexHelper vh)
    {

        vh.Clear();

        initVec = Vector3.zero;
        var vertex = UIVertex.simpleVert;
        vertex.color = color;

        var angle = GetAngle(initVec, vectors[0]) + 45f;
        vertex.position = initVec;

        vertex.position -= Quaternion.Euler(0, 0, angle) * (Vector3.right * thickness/2);
        vh.AddVert(vertex);

        vertex.position = initVec;
        vertex.position += Quaternion.Euler(0, 0, angle) * (Vector3.right * thickness/2);
        vh.AddVert(vertex);

        for (int i = 0; i < vectors.Count; i++)
        {
            DrawLine(vh, vectors[i], i);
        }

    }


    void DrawLine(VertexHelper vh, Vector3 point, int index)
    {
        var vertex = UIVertex.simpleVert; 

        vertex.color = color;
        var angle = GetAngle(initVec, point)+45f;

        vertex.position = point;
        vertex.position -= Quaternion.Euler(0, 0, angle) * (Vector3.right * thickness/2);
        vh.AddVert(vertex);

        vertex.position = point;
        vertex.position += Quaternion.Euler(0, 0, angle) * (Vector3.right * thickness/2);
        vh.AddVert(vertex);

        vh.AddTriangle(index * 2 + 0 , index * 2 + 1, index * 2 + 2);
        vh.AddTriangle(index * 2 + 2 , index * 2 + 3 , index * 2 + 1);
    }

    float GetAngle(Vector3 begin, Vector3 end)
    {
        return (float)(Mathf.Atan2(end.y - begin.y, end.x - begin.x) * (180 / Mathf.PI));
    }
}

위 부분에서 핵심은
vh.AddVert(Vertex ver) 와 AddTrinangle(int idx0, int idx1, int idx2)이다.

vertex.position = Vector3;
로 지점을 설정해주고,
AddVert해준다.
그러면 버텍스 배열에 들어가게 되고,
각 지점의 번호를 AddTrinangle의 인수로 넣어주면 삼각형을 그려준다.

그러면 삼각형이 나오고 그림이 그려진다!

그러면 예를 들어, (0,0)에서 (500, 500)으로 가는 선분을 그리고 싶다.
내가 선택한 방법은 평행사변형을 만드는 것이었다.

코드는


    void DrawLine(VertexHelper vh)
    {
        var vertex = UIVertex.simpleVert;

        vertex.position = new Vector3(0,0);
        vh.AddVert(vertex);

        vertex.position += (Vector3.right * thickness);
        vh.AddVert(vertex);

        vertex.position = new Vector3(500, 500);
        vh.AddVert(vertex);

        vertex.position +=  (Vector3.left * thickness);
        vh.AddVert(vertex);

        vh.AddTriangle(0, 1,  2);
        vh.AddTriangle( 2,  3, 0);
    }

이런식으로 작성하고,

이런 모습으로 보인다.

그러면 삼각형 두개를 붙인 사각형을 이어서 계속 만들면 선을 만들 수 있을 것 같다.

하지만 내 방법에서는 문제가 있다.
y가 같으면 두께가 없어진다는 것이다.

그를 위해 사각형을 회전하는 방식을 위 영상에서는 이용한다.

회전 각을 얻어내는 건 arctan을 이용하고,아래와 같다.

float GetAngle(Vector3 begin, Vector3 end)
    {
        return (float)(Mathf.Atan2(end.y - begin.y, end.x - begin.x) * (180 / Mathf.PI));
    }

또한 사각형도 중점을 기준으로 좌우로 이동하는 방식을 이용하였고,


위와 같은 점을 주었을 때,

위와같은 결과물을 얻을 수 있었다.

과정에서 이해가 안 되는 부분은.....
angle에서 45를 더해주는 부분인데.......

왜 더해줘야 하는 건지 잘 모르겠다.

profile
2020. 11월 공부시작.

0개의 댓글