해당 객체를 바라보기 위해서는 transform.LookAt을 많이 사용한다. 하지만 2D에서 이를 사용하면 Y축까지 회전하여 2D상에서 보이지 않게된다.
즉 객체의 정면(우리가 보는 면)이 해당 오브젝트한태 회전을 하기(Y축이 90도 회전)에 우리한태 보이지 않게 된다.
이거의 답은 쉬우면서 어렵다. 그게 무슨 개똥같은 소리냐 라고 말할 수 있지만 실제로 그렇다...
어려운 이유는 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);
target.transform.position - transform.position
Mathf.Atan2(newPos.y, newPos.x)
Mathf.Atan()가 아닌 Mathf.Atan2()를 사용한 이유
Mathf.Atan()는 1개의 파라미터를 받아 높이와 밑변에 동일한 값을 넣는다. 하지만 0을 넣으면 y가 0이 되어 오류가 발생한다.
이를 해결하기 위해 Mathf.Atan2()가 생겼다. 2개의 값을 입력받아 오류가 발생하지 않는다.
Mathf.Rad2Deg;
위의 수식으로 나온 값은 각도 단위 라디안(6.28 = 2π
를 기준으로 만든 각도)을 도로 변환합니다.
쉽게말해 6.28 = 360도 입니다.
Quaternion
(쿼터니언)으로 되어있습니다. rotation의 값을 변경하기 위해서는 동일한 타입인 쿼터니언으로 입력해줘야 변경되기에 진행합니다.Quaternion Euler(float x, float y, float z);
여기서 z축만 변경하면 해당 방향으로 바라보게 됩니다.(x축의 상하 반전, Y축은 좌우 반전)
transform.rotation = Quaternion.Euler(0, 0, rotZ);
이 절차를 따라주면 내가 원하는 객체의 방향으로 변경해줄수 있습니다.
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
에 이동속도를 곱해서 넣어주면 된다.
1번과 동일하다 단지 z방향을 내가 설정해 줄 뿐이다.
이것은 첫번째랑 거의 비슷하다.
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()
이다.