Unity - 2D 원하는 객체 바라보기 및 발사하

김도현·2023년 9월 13일
0

TIL

목록 보기
37/76

이 글을 쓰는 이유

해당 객체를 바라보기 위해서는 transform.LookAt을 많이 사용한다. 하지만 2D에서 이를 사용하면 Y축까지 회전하여 2D상에서 보이지 않게된다.
즉 객체의 정면(우리가 보는 면)이 해당 오브젝트한태 회전을 하기(Y축이 90도 회전)에 우리한태 보이지 않게 된다.

그래서 2D에서는 어떻게 객체를 바라보게 만드냐?

이거의 답은 쉬우면서 어렵다. 그게 무슨 개똥같은 소리냐 라고 말할 수 있지만 실제로 그렇다...
어려운 이유는 LookAt처럼 2D에서 해당 객체를 바라보는 명령어가 없기에 실제로 작성해야 되는데 여기서 수학적으로 계산해야된다.
그러면서 쉬운 이유는 방법과 원리를 알고있으면 간단코드여서 복붙처럼 사용할 수 있다.

코드

Vector2 newPos = target.transform.position - transform.position;
float rotZ = Mathf.Atan2(newPos.y, newPos.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0, 0, rotZ);

해석

  1. 두 점간의 거리를 구한다. target.transform.position - transform.position
    두 점간 거리 구하기
  2. 각도를 구한다. Mathf.Atan2(newPos.y, newPos.x)
    아크 탄젠트(arctan)에 높이(Y)와 밑변을(X)를 넣어 각도를 구한다.
    => 아크 탄젠트는 탄젠트의 반대이다 (탄젠트는 각도를 넣어 높이/밑변을 구한다).

    Mathf.Atan()가 아닌 Mathf.Atan2()를 사용한 이유
    Mathf.Atan()는 1개의 파라미터를 받아 높이와 밑변에 동일한 값을 넣는다. 하지만 0을 넣으면 y가 0이 되어 오류가 발생한다.
    이를 해결하기 위해 Mathf.Atan2()가 생겼다. 2개의 값을 입력받아 오류가 발생하지 않는다.

  1. 라디안을 각도로 변경해 줍니다.
Mathf.Rad2Deg;

위의 수식으로 나온 값은 각도 단위 라디안(6.28 = 를 기준으로 만든 각도)을 도로 변환합니다.
쉽게말해 6.28 = 360도 입니다.

  1. 각도(오일러각)를 쿼터니언으로 변경해 줍니다.
    rotation의 값은 Quaternion(쿼터니언)으로 되어있습니다. rotation의 값을 변경하기 위해서는 동일한 타입인 쿼터니언으로 입력해줘야 변경되기에 진행합니다.
Quaternion Euler(float x, float y, float z);

여기서 z축만 변경하면 해당 방향으로 바라보게 됩니다.(x축의 상하 반전, Y축은 좌우 반전)

  1. 쿼터니언값을 rotation에 적용
transform.rotation = Quaternion.Euler(0, 0, rotZ);

이 절차를 따라주면 내가 원하는 객체의 방향으로 변경해줄수 있습니다.

발사하기

1. 내가 바라보고 있는 방향으로 쏘기

float z = transform.rotation.eulerAngles.z;
Vector2 direction = new Vector2(Mathf.Cos(z * Mathf.Deg2Rad), Mathf.Sin(z * Mathf.Deg2Rad));
GetComponent<Rigidbody2D>().velocity = direction * Speed;

원리는 같다 내가 바라보고있는 각도를 이용해 X축(밑변), Y축(밑변)을 구한다음 .velocity이나 .AddForce에 이동속도를 곱해서 넣어주면 된다.

2. 그냥 내가 원하는 방향으로 쏘기

1번과 동일하다 단지 z방향을 내가 설정해 줄 뿐이다.

3. 타겟 방향으로 쏘기

이것은 첫번째랑 거의 비슷하다.

코드

Vector2 newPos = (target.transform.position - transform.position).Normalize();
GetComponent<Rigidbody2D>().velocity = newPos * Speed;

원리

상대위치에서 내 위치를 빼면 상대적인 거리가 나오는데 여기서 x와 y값을 크기를 단위벡터(x,y를 합치면 무조건 1이 나오는 벡터)로 변경해준다.
예시 내 위치가 (0, 0)일 때 상대 위치가 (5, 2)라고 한다 그러면 상대적인 거리가 (5, 2)이다. 여기서 이동속도를 곱해주면 너무 빠른 속도가 나오게 된다.
이를 단위벡터로 변경해줘서 어떠한 각도에서든 이속이 1이 되도록 만들어주는 역할이 .Normalize()이다.

0개의 댓글