[Unity3D] 조이스틱으로 캐릭터 조종하기. [Part 1]

※ 주의 

이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.



Menu


1. 조이스틱 만들기.

2. 조이스틱의 벡터를 받아 캐릭터를 회전 및 이동 시키기.



완성작 미리보기




1. 조이스틱 만들기.



1). 이미지 준비.

- 조이스틱의 배경 이미지.

- 조이스틱 이미지.




2). 캔버스 준비.


UI이미지를 따로 관리해주는 객체가 있다.

하이러키창에서 마우스 오른쪽버튼을 클릭해 보면 UI라는 메뉴가 있는데,

이 메뉴안에 있는 여러가지 목록들을 선택하면 목록에 있는 객체가 생성된다.


만약 하이러키창에 캔버스가 없으면 캔버스를 자동으로 생성시키고 캔버스의 자식으로

우리가 선택한 목록을 생성시킨다.


더불어 EventSystem이라는 객체도 생성시키는데, 이 객체는 각종 UI이벤트에 필요한 객체이다.

이객체는 우리가 따로 건드릴 필요는 없다. 




이미지를 2개 생성시킨다.

첫 번째 이미지의 이름은 JoyStickBackGround

두 번째 이미지의 이름은 JoyStick




그리고 객체를 하나씩 선택해서 이미지를 넣자.





2개의 이미지를 겹쳐 한쪽 구석에 이쁘게 정리하도록 하자.




정리가 끝났으면

JoyStick을 배경의 자식으로 넣는다.




하이러키창에 조이스틱 객체를 누르고 Add Componenet를 누른다.

그리고 Event Trigger라고 검색하면 하나의 컴포넌트가 나온다.

추가하도록 하자.



이 컴포넌트에는 UI에 대하여 여러가지 이벤트를 수행할 수 있다.



그 중에서 우리가 사용할 것은 드래그와 끝 드래그 이다.

이러한 컴포넌트를 조이스틱 객체에다 만든 이유는

조이스틱객체를 터치하여 움직이게 할 것이기 때문이다.




드래그와 드래그 끝 2개를 추가시켜주자.



다음은 스크립트를 작성하도록 하자.

스크립트의 이름은 JoyStick이다.

이 스크립트는 JoyStickBackGround에 넣도록 하자.


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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
 
public class JoyStick : MonoBehaviour {
 
    // 공개
    public Transform Stick;         // 조이스틱.
 
    // 비공개
    private Vector3 StickFirstPos;  // 조이스틱의 처음 위치.
    private Vector3 JoyVec;         // 조이스틱의 벡터(방향)
    private float Radius;           // 조이스틱 배경의 반 지름.
 
    void Start()
    {
        Radius = GetComponent<RectTransform>().sizeDelta.y * 0.5f;
        StickFirstPos = Stick.transform.position;
 
        // 캔버스 크기에대한 반지름 조절.
        float Can = transform.parent.GetComponent<RectTransform>().localScale.x;
        Radius *= Can;
    }
 
    // 드래그
    public void Drag(BaseEventData _Data)
    {
        PointerEventData Data = _Data as PointerEventData;
        Vector3 Pos = Data.position;
        
        // 조이스틱을 이동시킬 방향을 구함.(오른쪽,왼쪽,위,아래)
        JoyVec = (Pos - StickFirstPos).normalized;
 
        // 조이스틱의 처음 위치와 현재 내가 터치하고있는 위치의 거리를 구한다.
        float Dis = Vector3.Distance(Pos, StickFirstPos);
        
        // 거리가 반지름보다 작으면 조이스틱을 현재 터치하고 있는곳으로 이동. 
        if (Dis < Radius)
            Stick.position = StickFirstPos + JoyVec * Dis;
        // 거리가 반지름보다 커지면 조이스틱을 반지름의 크기만큼만 이동.
        else
            Stick.position = StickFirstPos + JoyVec * Radius;
    }
 
    // 드래그 끝.
    public void DragEnd()
    {
        Stick.position = StickFirstPos; // 스틱을 원래의 위치로.
        JoyVec = Vector3.zero;          // 방향을 0으로.
    }
}
 
cs




Stick변수는 조이스틱을 움직이기 위해 필요하다.

StickFirstPos변수는 조이스틱의 처음 위치가 들어가 있는데,

조이스틱을 움직이기 위해서는 처음 위치에다가 움직일 거리를 더해줄 필요가 있다.

처음위치 + 방향 * 거리 방식으로 움직여야 한다.

그리고, 드래그하다가 터치를 땠을 때 조이스틱은 원래의 위치로 돌아갈 필요가 있는데,

그 원래에 위치로 돌려주기위한 위치 값 저장 이기도 하다.




JoyVec은 현재 조이스틱에 대한 방향을 저장해줄 벡터 변수이다.

Radius는 배경 그림에 대한 반지름의 크기를 넣을 것이다.

조이스틱이 배경 이미지 바깥으로 넘어가지 못하게 하기 위함이다.



다음은 Drag함수이다.

모든 UI이벤트는 사실 레이캐스트로 작동하고 있다.

그렇기 때문에 이미지에 존재하는 Raycast Tartget을 해제하면 터치 이벤트가 작동하지 않는다.




아무튼, 터치에 대한 정보는 EventSystem에 저장되는데, UI메뉴중 아무거나 생성시키면 같이 생성되는 이유는 그 때문이다.



이 EventSystem에는 터치 정보 말고도 여러가지 정보가 저장되어있다.

그렇기 때문에 그 정보를 꺼내 쓰기 위해서 유징해줄 필요가 있는데,

스크립트에 맵 위에 보면 UnityEngine.EventSystems;이 유징되어 있는것을 볼 수 있다.



조이스틱을 움직이기 위해서는 현재 터치되는 위치가 어디인지 알 필요가 있다.

그 위치에 대한 정보는 BaseEventData에 들어있는데, 이 자료형을 사용하려면 EventSystems가 유징되어있어야 한다.


이벤트 트리거에서 잘 보면 BaseEventData을 인자로 받는것을 볼 수 있다.


베이스 이벤트 데이터를 인자로 받아

그 데이터를 PointerEventData 변수에 형변환 시킨뒤 저장한다.


※ PointerEventData : 마우스 및 터치에 대한 이벤트.


BaseEventData을 이용하고 있기 때문에 터치 포인트에 대해서는 따로 쓰게 된다.

무슨말이냐면 쉽게 말해서 이러한 조이스틱말고 또 다른 버튼이벤트 같은것이 있을 경우

터치 포인터를 공유해서 쓰지않고 따로따로 쓴다는 말이다.


한 줄로 요약해서 멀티터치가 가능하다는 소리다.



나머지 구문들은 스크립트에 주석으로 설명이 되어있기 때문이 생략하겠다.





결과