본문 바로가기

Unity

Unity - 조이스틱(Joystick)

2D게임에서 흔한 조이스틱을 구현해보기

 

실습환경은 다음과 같음

 

1. canvas를 만들어 터치가 가능한 Area 만들기 (여기서는 화면의 1/2를 사용했음)

   - canvas는 Screen Space - Camera로 바꾸고 Scaler도 Scale With Screen Size로 바꿈 (x : 1080, y : 1920)

   - Area는 앵커를 그대로 두고 Rect Tool로 임의로 바꿔줌

2. 조이스틱 범위를 설정할 outer 만들기 (Image, height 500 width 500)

3. 조이스틱 움직임을 표현할 inner 만들기 (Image, height 150)

4. Joystick.cs 스크립트 작성하여 Area에 넣어주기

 

 

touch관련은 Unity에서 EventSystem에서 관리함

 

여기에 포함되어있는 인터페이스와 라이브러리를 활용하여 조이스틱을 쉽게 구현할 수 있음

 

조이스틱은 Drag, PointerUp, PointerDown 때 활용되므로 인터페이스를 상속받아 사용함

 

각각의 인터페이스의 함수를 상속받았으므로 함수를 오버라이딩 해야함

 

 

누를 당시와 누르고 있을때의 움직임에 대한 inner 이미지를 옮겨주면 됨

그래서 OnDrag와 OnPointDown에 inner 이미지에 대한 스크립트를 작성해 주면 됨

 

또한 터치를 그만두는 순간 inner 이미지를 다시 원상태로 복귀 시켜야 함

그래서 OnPointerUp에 inner 이미지 위치를 원상태로 복귀시켜주는 스크립트를 작성해주면 됨

 

그리고 터치했을 당시 가지고 있는 좌표는 카메라 기준 ScreenPoint인데 이것을 가지고 연산하기에는 복잡함

우리는 ScreenPoint의 위치보다는 joystick의 중심으로 하는 LocalPoint를 사용할 것

이것을 편리하게 해주는 API 존재 -> 이것을 사용하여 localVector를 얻어 올 것임

 

RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, Vector2, Camera, out Vector2)

첫번째 인자값 RectTransform에는 Area를 넣어줌

두번째 인자값 Vector2는 상속받은 인터페이스 함수의 매개변수에 있는 eventData.point를 사용

세번째 인자값 Camera는 상속받은 인터페이스 함수의 매개변수에 있는 eventData.pressEventCamera를 사용

네번째 인자값 out Vector2에는 localVector가 반환되서 나오니 선언하여 넣어주면 됨

 

설명을 하자면 touch한 부분의 좌표를 ScreenPoint에서 LocalPoint로 바꿔주는 부분인 것

그래서 ScreenPoint에 대한 정보를 두번째, 세번째 인자값에 넣어주는 것

 

 

 

전체코드를 보면 다음과 같음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; //image 사용을 위함
using UnityEngine.EventSystems; //인터페이스사용
 
public class Joystick : MonoBehaviour, IDragHandler, IPointerDownHandler, IPointerUpHandler
{
    public RectTransform touchArea;
    public Image inner;
 
    public void OnDrag(PointerEventData eventData)
    {
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(touchArea,
            eventData.position, eventData.pressEventCamera, out Vector2 localVector))//if문에서 API사용
       {
            if(localVector.magnitude < 200//outer안에 있다면 //200이란 수치는 임의로 작성
                inner.transform.localPosition = localVector;
            else                            //outer밖에 있다면 위치 고정
                inner.transform.localPosition = localVector.normalized * 200;
            
            //localVector를 가지고 놀기
        }
    }
 
    public void OnPointerDown(PointerEventData eventData)
    {
        OnDrag(eventData); //OnDrag와 같은 로직
    }
 
    public void OnPointerUp(PointerEventData eventData)
    {
        inner.transform.localPosition = Vector2.zero; //inner의 위치를 복귀 시켜줌
    }
}
 
cs

 

 

반환 받은 localVector를 가지고 플레이어를 회전시키거나 이동하거나 하면 끝

'Unity' 카테고리의 다른 글

Unity - 인디케이터(Indicator)구현  (0) 2020.02.19
Unity - 총알 구현하기(Bullet)  (0) 2020.02.17
Unity - 스폰(Spawn) 구현하기  (0) 2020.02.17
Unity - 무한 배경(Loop Background)  (2) 2020.02.12
Unity Asset Store 세일  (0) 2019.11.11