[Unity] Vector2.Angle의 사용

·2024년 6월 24일
0

Unity

목록 보기
4/11
post-thumbnail

유니티에서 내적을 사용하여 두 벡터간의 각도를 구하기 위해서는
1. Vectordot product를 활용해 단위벡터의 내적 값을 구하거나
2. Vector2.angle 함수를 활용해 구하는 방법이 있다.

물론 원리는 같고 필자는 2번의 함수를 사용하여 원하는 결과를 배출했다!

🌳 구현하고자 하는 상황

플레이어가 바라보는 방향과 마우스 커서의 위치를 기준으로 그 사이각을 구해 손전등을 구현하고자 했다 🔦

👀 구현된 결과물

💻 구현 과정

일단 플레이어와 마우스 위치간의 ☝️방향벡터가 필요했다.
하지만 플레이어의 위치는 world 좌표계이고, 유니티 Input에서 제공하는 mouse는 screen 좌표계를 사용하였기에 두 오브젝트의 좌표계를 통일시켜 벡터를 구해야하는 것이 선제조건이 되었다.

Vector3 worldMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

필자는 월드를 기준으로 손전등의 위치를 조정하고자 하기에 마우스의 위치를 우선 월드 좌표계로 바꿨다

구해진 마우스의 월드 좌표와 플레이어의 좌표를 빼서 mouseDir 벡터를 구해준 뒤,
마우스가 위치한 방향에 맞춰 회전 각도를 조정하기 위해 mouseDir.x가 0보다 크면 오른방향이므로 Vector2.right와 mouseDir를 Vector2.Angle 함수의 매개변수로 입력해준다.
반대인 경우에는, Vector2.left를 매개변수로 입력해주고 결과로 나온 angle을 손전등의 rotation.x에 갱신해준다.

참고로 Vector2.Angle은 0~180도의 부호없는 사이각만 반환하기에 부호가 있는 값을 위해서는 필자가 부호를 취해주어야한다.

따라서 mouseDir.y의 값을 0을 기준으로, 방향에 맞춰 반환된 angle의 값에 적절히 부호를 바꿔서 조건문을 걸어주면 위와 같은 결과물을 받아볼 수 있다.

💬 추가로 특정 범위에서만 작동하도록, Mathf.Clamp 함수를 사용해줬다

🔗 최종 구현 코드

float theta, angleY;

    void Update()
    {
        Vector3 worldMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        Vector3 dir = worldMousePos - transform.position;
        if (dir.x > 0)
        {// right
            angleY = 90f;
            theta = Vector2.Angle(Vector2.right, dir);
            transform.localPosition = new Vector3(-1.25f, 0, 1.25f);

        }
        else
        {// left
            angleY = -90f;
            theta = Vector2.Angle(Vector2.left, dir);
            transform.localPosition = new Vector3(1.25f, 0, 1.25f);
        }

        theta = Mathf.Clamp(theta, 0, 35);
        if (dir.y < 0)
        {
            transform.rotation = Quaternion.Euler(theta, angleY, 0);
        }
        else
        {
            transform.rotation = Quaternion.Euler(-theta, angleY, 0);
        }
    }
profile
할 수 있는 최선을 다하는 클라이언트 개발자랍니다 (❁´◡`❁)

0개의 댓글

관련 채용 정보