오늘은 프로젝트 B에서 진행한 곡선 UI를 그리는 작업을 공유하고자 한다.

우선 Line을 그리기 위해 유니티 Effects의 Line 오브젝트를 생성해주도록 하자.

오브젝트를 생성한다면 Line Renderer 컴포넌트가 포함되어 있을 것이다.

여기서 우리가 중점으로 봐야할 부분은 Positions 속성이다.

대충 값을 대입하다보면 해당 Position들은 점들의 위치이며 두개의 점을 이어 Line을 그려준다는 것을 알 수 있다.

 

우선 한 정점을 기준으로 마우스 커서 까지 이어주는 직선 형태의 Line을 그려보도록 하자.

public class StraightLine : MonoBehaviour
{
    [SerializeField] private LineRenderer line;
    
    void Start()
    {
        line.positionCount = 2;
        line.SetPosition(0, Vector2.zero);
    }

    void Update()
    {
        var _mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        line.SetPosition(1, _mousePos);
    }
}

직선은 정점 두개로 이루어지기 때문에 positionCount를 2로 초기화 해주었다.

나는 시작점을 (0, 0)으로 설정해주었고 마우스 position을 월드 좌표로 변환하여 끝점에 대입해주었다.

 

하지만 내가 구현해야하는 방식은 직선이 아닌 곡선이다보니 위의 방식과는 다르게 가야한다.

곡선을 구현하기 위한 아이디어를 찾기 위해 인터넷 검색을 통해 알아본 결과 베지어 곡선을 이용해야한다는 것을 알게 되었다.

 

베지어 곡선이란? n개의 조절점을 가지고 선형 보간을 통해 곡선 형태를 이루는 점들의 집합을 구하는 공식이다.

베지어 곡선에 대한 자세한 내용은 아래의 블로그를 참고하자!

https://ko.javascript.info/bezier-curve

 

베지어 곡선

 

ko.javascript.info

해당 프로젝트에서 그리는 곡선은 이차 함수의 모양 형태로 그려야하기 때문에 조절점이 3개인 2차 베지어 곡선의 식을 참고하여 구현해보았다.

https://namu.wiki/w/%EB%B2%A0%EC%A7%80%EC%97%90%20%EA%B3%A1%EC%84%A0

위의 식을 참고하여 코드로 나타내면 다음과 같다.

public int segmentCount = 20;
public float controlPointY = 1f;

private Vector2 CalculateQuadraticBezierPoint(Vector2 p1, Vector2 p2, Vector2 p3, float t)
{
    var _u = 1 - t;
    var _tt = t * t;
    var _uu = _u * _u;

    Vector2 _point = _uu * p1;
    _point += 2 * _u * t * p2;
    _point += _tt * p3;

    return _point;
}

private void DrawBezierCurve(Vector2 endPos)
{
    var _positions = new Vector3[segmentCount + 1];
    line.positionCount = segmentCount + 1;

    var _p1 = Vector3.zero;
    var _p3 = endPos;

    var _p2 = new Vector3((_p1.x + _p3.x) * 0.5f, _p1.y + controlPointY, 0f);

    for (int i = 0; i < segmentCount + 1; i++)
    {
        float _t = (float)i / segmentCount;
        _positions[i] = CalculateQuadraticBezierPoint(_p1, _p2, _p3, _t);
    }

    line.SetPositions(_positions);
}

p1과 p3는 각각 시작점과 끝점으로 대입해주었으며 p2 조절점의 경우 p1과 p3의 중점으로 두었다.

점의 갯수가 많을 수록 더 부드러운 곡선을 연출할 수 있으므로 20개 정도로 임의의 값을 넣어 실행해보았다.

실행한 결과 만족스러운 결과가 나왔다.

여기서 조절점의 위치를 조절해서 원하는 곡선 형태로 만들어준다면 더 이쁘게 나올거 같다.

부족함이 많은 코드인만큼 더 좋은 방식이 있다면 댓글로 추천해주시면 감사하겠습니다!

+ Recent posts