본문 바로가기
ETC/Unity

[유니티] 마우스 방향으로 2D Object 회전시키는 방법

by Gnaseel 2020. 2. 29.
728x90
반응형

유니티 카테고리 안에 있지만 사실은 거의 수학적인 내용이다.

개발을 하다보면 2D object를 회전시켜야 할 일이 있는데, 우리가 보통 object에서 가장 쉽게 구할 수 있는 것은 위치값 또는 벡터 값이다.

 

위치를 원점에서의 벡터라고 생각한다면 사실상 두 값의 의미는 같다.

 

 

오늘 구현하고자 하는 내용은 아래와 같다.

 

 

마우스를 따라 화살표가 움직인다.

이와같이 마우스 커서의 이동에 따라 오브젝트를 움직이는 것이다.

3D같은경우는 Lookat 등을 써서 target과 player 사이에 손쉽게 해결하는 것 같지만 위와 같은 경우는 다르다.

 

1. Vector 값이 world 좌표가 아닌 screen의 좌표 값이다.

2. 입체적으로 회전하는 3D와 다르게 Z축만을 회전시켜 구현해야 한다.

 

이 두 가지가 다르기 때문에 직접 구현했다.

 	float angle;
    Vector2 target, mouse;
    
   	 private void Start()
   	 {
   	     target = transform.position;
   	 }
   	 private void Update()
   	 {
   	     mouse = Camera.main.ScreenToWorldPoint(Input.mousePosition);
   	     angle = Mathf.Atan2(mouse.y - target.y, mouse.x - target.x) * Mathf.Rad2Deg;
   	     this.transform.rotation = Quaternion.AngleAxis(angle-90, Vector3.forward);
  	  }

angle은 기준으로부터 몇 도 회전했는지 담을 변수이고,

target과 mouse는 말그대로 각각 화살표, 마우스의 Vector2 값이다.

 

Start메소드는 생략하고 Update부터 설명하겠다.

 

 mouse = Camera.main.ScreenToWorldPoint(Input.mousePosition);

우선 메인 카메라 에서 Screen좌표계의 마우스 위치를 입력받아 월드 좌표로 변환한 후,

mouse에 대입해준다.

 

 angle = Mathf.Atan2(mouse.y - target.y, mouse.x - target.x) * Mathf.Rad2Deg;

여기서부터 자세하게 설명해야 할 것 같다.

우선 Mathf.Atan2는 레퍼런스 를 확인해보면

 

라고 되어있다.

탄젠트 값으로 y/x값을 가지는 radian을 반환해주는 것이다.

 

mouse에서 target의 벡터를 빼면 target에서 mouse로 향하는 방향의 벡터가 되는데,

그 벡터값의 x, y 성분을 이용해서 해당 탄젠트 값을 가지는 각도를 찾아 radian으로 반환해 주는 것이다.

 

그리고 Mathf.Rad2Deg 는 말 그대로 radian to degree다. 

1파이 radian= 180도

라는 기존 계산식을 이용해서 변환하는데,

특별한 기능을 하는 메소드가 아니라 57.29578값을 반환해주는 읽기전용 함수이다.

 

즉, mouse에서 target의 벡터를 감산해서 mouse에서 target으로 향하는 벡터를 구한 후,

그 벡터 값의 x, y 성분을 이용해서 해당 탄젠트 값을 갖는 각도를 radian형태로 구하고, Rad2Deg상수를 곱해서

우리가 일반적으로 사용하는 각도의 형태로 변환해주는 과정인 것이다.

 

이제 어려운 부분은 끝났다.

 

 this.transform.rotation = Quaternion.AngleAxis(angle-90, Vector3.forward);

이 물체(target)의 각도를 회전시키는데, AngleAxis 라는 함수를 사용한다.

레퍼런스 주소도 첨부한다.

 

 

첫 번째 인자인 angle만큼, 두 번째 인자인 axis를 기준축으로 회전한 값을 반환한다라고 되어있다.

유니티에서 Vector3.forward는 (0, 0, 1)값을 반환해주고, 이것은 x, y가 0이고 z가 1이기 때문에

z축을 중심으로만 회전시킨다는 의미이다.

90도를 빼는 이유는 좌표평면 위에서 X축을 기준으로 시작하기 때문이다.

x축을 기준으로 몇 도 차이가 나는지 반환하기 때문에 마우스를 완전히 화살표의 오른쪽에 놓는다면,

angle은 0을 가르킨다.

하지만 우리 인간의 기준으로는 마우스가 화살표의 오른쪽에 있다면 화살표가 오른쪽으로 90도 회전해야 맞다.

 

이렇게 기준이 다르기 때문에 90도를 감산해줘야 정확한 각도로 회전하게 된다.

반응형

댓글2

  • 안녕하세요 2022.04.26 09:01

    안녕하세요. 여쭈어 볼 것이 있습니다.
    제가 오브젝트를 2개 만들고 저 스크립트를 넣으면 오브젝트 2개가 동시에 회전합니다.
    그래서 오브젝트 2개를 버튼 2개로 바꾸어서 스크립트를 OnClick에 넣고 실행시키려 했으나 움직이지 않았습니다.
    어떻게 해야할 지 알려주실 수 있나요?
    답글

  • 민냐옹 2022.06.07 23:58 신고

    정말 좋은 글이네요. 감사합니다 :)
    답글