본문 바로가기
Unity 공부

[Unity] 베지어 곡선 활용해 오브젝트 곡선 이동 시키기

by 개발하는 디토 2022. 11. 3.

목표

베지어 곡선을 활용해 오브젝트가 예쁜 곡선을 그리며 이동하게 할 수 있다.

 

참고한 영상은 여기

 

Bezier 곡선을 따라 이동하는 오브젝트 구현

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class BezierCurve : MonoBehaviour
{

    public GameObject obj;
    [Range(0, 1)]
    public float testVal = 1;
    [SerializeField]
    public float moveSpeed = 0.0001f;
    public Vector3 P1;
    public Vector3 P2;
    public Vector3 P3;
    public Vector3 P4;

    private void Update()
    {
        testVal -= moveSpeed;
        obj.transform.position = BezierTest(P1, P2, P3, P4, testVal);

        if (testVal <= 0)
        {
            testVal = 1;
        }
    }
    public Vector3 BezierTest(Vector3 P_1, Vector3 P_2, Vector3 P_3, Vector3 P_4, float value)
    {

        Vector3 A = Vector3.Lerp(P_1, P_2, value);
        Vector3 B = Vector3.Lerp(P_2, P_3, value);
        Vector3 C = Vector3.Lerp(P_3, P_4, value);

        Vector3 D = Vector3.Lerp(A, B, value);
        Vector3 E = Vector3.Lerp(B, C, value);

        Vector3 F = Vector3.Lerp(D, E, value);
        return F;
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawSphere(P1, 0.5f);
        Gizmos.DrawSphere(P2, 0.5f);
        Gizmos.DrawSphere(P3, 0.5f);
        Gizmos.DrawSphere(P4, 0.5f);
    }
}

// not working....

//[CanEditMultipleObjects]
//[CustomEditor(typeof(BezierCurve))]

//public class BezierEditor : Editor
//{
//    private void OnScreenGUI()
//    {
//        BezierCurve generator = (BezierCurve)target;
//        Handles.PositionHandle(generator.P1, Quaternion.identity);
//        Handles.PositionHandle(generator.P2, Quaternion.identity);
//        Handles.PositionHandle(generator.P3, Quaternion.identity);
//        Handles.PositionHandle(generator.P4, Quaternion.identity);

//    }
//}

 

원래 영상대로라면 Vector3 핸들이 나와서 에디터 창에서 각 지점을 움직이게끔 할 수 있는데 나는 저 코드가 안 먹혀서 그냥 Inspector 상에서 수치를 입력하는 것으로 해결했다. OnDrawGizmos()에 의해 P1, P2, P3, P4 지점을 Scene View에 표시했다.

Scene View에 베지어 곡선을 만들기 위한 P1~P4가 어디쯤 있는지 보이게 된다.
Bezier 곡선 이동용 Script

빈 오브젝트에 Bezier Curve 스크립트를 연결 후 움직이고 싶은 GameObject를 Obj에 연결한다.

Inspector 창에서 P1, P2, P3, P4의 위치를 조정한다. 그러면 베지어 곡선이 만들어지는데 이 베지어 곡선 상의 위치가 BezierTest의 return 값이다. 움직일 속도를 Move Speed로 입력하면 그 값이 testVal에서 조금씩 빠지면서 오브젝트가 오른쪽에서 왼쪽으로 이동하게 된다.

오른쪽에서 왼쪽으로 이동하게 하려면 testVal의 초기값을 1로 두고 testVal -= moveSpd 를 적용하면 되고, 왼쪽에서 오른쪽으로 이동하게 하려면 testVal의 초기값을 0으로 두고 testVal += moveSpd를 적용하면 된다. Update의 if 절은 testVal이 다른 한쪽 끝값에 도달했을 때 다시 초기 위치(1)로 돌려놓는 것인데 내 코드의 경우 오른쪽에서 왼쪽으로 이동한 뒤 다시 오른쪽으로 가서 베지어 곡선상의 이동을 진행한다. 좌우로 움직이고 싶다면 testVal+=moveSpd로 오브젝트를 움직이고 if(testVal <=0 || testVal >=1) 일 때 moveSpd에 -1을 곱해 부호를 반대로 바꿔주면 왼쪽으로 갔다~오른쪽으로 갔다~ 곡선 이동을 반복하는 움직임을 만들 수 있을 것이다.

댓글