팀프로젝트/R&D

2020.06.09. 조이스틱 구현하기 / 조이스틱 방향으로 캐릭터 회전

dev_sr 2020. 6. 9. 22:12

가속도 없이 이동 + 조이스틱 방향으로 캐릭터를 회전

 

 

 

 

 

조이스틱의 방향값 ( x, y) 을 아크탄젠트로 변환시키고 라디안을 디그리 값으로 변환시켜준 값을 곱해준 뒤

캐릭터의 Y축 변환값으로 넣어줌

 

if (this.value != null)

            {

                this.go_Player.transform.rotation = Quaternion.Euler(0f, 

                                                                     Mathf.Atan2(this.value.x, this.value.y) * Mathf.Rad2Deg, 

                                                                     0f);

            }

 

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems; //터치와 관련된 인터페이스를 가져올 거임
                                //마우스 클릭 시작했을 때  //마우스 손 땠을 때  //드래그 했을 때
public class Test : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
    //이 스크립트는 백그라운드에 어사인 해줌
    //터치에 반응할 부분은 백그라운드이기 때문
 
    //움직이는 범위를 제한하기 위해서 선언함
    [SerializeField] private RectTransform rect_Background;
    [SerializeField] private RectTransform rect_Joystick;
 
    //백그라운드의 반지름의 범위를 저장시킬 변수
    private float radius;
 
    //화면에서 움직일 플레이어
    [SerializeField] private GameObject go_Player;
    //움직일 속도
    [SerializeField] private float moveSpeed;
 
    //터치가 시작됐을 때 움직이거라
    private bool isTouch = false;
    //움직일 좌표
    private Vector3 movePosition;
 
    private Animation anim;
    //캐릭터 회전값을 만들기위해 value를 전역변수로 설정함
    private Vector2 value;
 
    void Start()
    {
        //inspector에 그 rect Transform에 접근하는 거 맞음
        //0.5를 곱해서 반지름을 구해서 값을 넣어줌
        this.radius = rect_Background.rect.width * 0.5f;
 
        this.anim = this.go_Player.GetComponent<Animation>();
 
    }
 
    //이동 구현
    void Update()
    {
        if (this.isTouch)
        {
            this.go_Player.transform.position += this.movePosition;
            //조이스틱 방향으로 캐릭터 회전
            if (this.value != null)
            {
                this.go_Player.transform.rotation = Quaternion.Euler(0f, 
                                                                     Mathf.Atan2(this.value.x, this.value.y) * Mathf.Rad2Deg, 
                                                                     0f);
            }
        }
    }
 
 
 
    //인터페이스 구현
 
    //눌렀을 때(터치가 시작됐을 때)
    public void OnPointerDown(PointerEventData eventData)
    {
        this.isTouch = true;
    }
 
    //손 땠을 때
    public void OnPointerUp(PointerEventData eventData)
    {
        //손 땠을 때 원위치로 돌리기
        rect_Joystick.localPosition = Vector3.zero;
 
        this.isTouch = false;
        //움직이다 손을 놓았을 때 다시 클릭하면 방향 진행이 되는 현상을 고침
        this.movePosition = Vector3.zero;
 
        this.anim.Play("idle@loop");
    }
 
    //드래그 했을때
    public void OnDrag(PointerEventData eventData)
    {
        //마우스 포지션(x축, y축만 있어서 벡터2)
        //마우스 좌표에서 검은색 백그라운드 좌표값을 뺀 값만큼 조이스틱(흰 동그라미)를 움직일 거임
        this.value = eventData.position - (Vector2)rect_Background.position;
 
        //가두기
        //벡터2인 자기자신의 값만큼, 최대 반지름만큼 가둘거임
        value = Vector2.ClampMagnitude(value, radius);
        //(1,4)값이 있으면 (-3 ~ 5)까지 가두기 함
 
        //부모객체(백그라운드) 기준으로 떨어질 상대적인 좌표값을 넣어줌
        rect_Joystick.localPosition = value;
 
        //value의 방향값만 구하기
        value = value.normalized;
        //x축에 방향에 속도 시간을 곱한 값
        //y축에 0, 점프 안할거라서
        //z축에 y방향에 속도 시간을 곱한 값
        this.movePosition = new Vector3(value.x * moveSpeed * Time.deltaTime,
                                        0f,
                                        value.y * moveSpeed * Time.deltaTime);
 
        this.anim.Play("run@loop");
    }
}

 

 

참고

 

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

※ 주의 이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다. Menu 1. 조이스틱 만들기. 2. 조이스틱의 벡터를 받아 캐릭터를 회전

truecode.tistory.com

 

유니티 조이스틱 이동 및 회전

유니티 조이스틱 이동 및 회전​1. 조이스틱 에셋 다운 (무료)​2. 캔버스에 Fixed Joystick 프리펩 추가...

blog.naver.com

 

 

 

-----------------------------------------------------------------------------------------------------------------------------------------------

이동

1. 가속이 없을 경우

 

 

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems; //터치와 관련된 인터페이스를 가져올 거임
                                //마우스 클릭 시작했을 때  //마우스 손 땠을 때  //드래그 했을 때
public class Test : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
    //이 스크립트는 백그라운드에 어사인 해줌
    //터치에 반응할 부분은 백그라운드이기 때문
 
    //움직이는 범위를 제한하기 위해서 선언함
    [SerializeField] private RectTransform rect_Background;
    [SerializeField] private RectTransform rect_Joystick;
 
    //백그라운드의 반지름의 범위를 저장시킬 변수
    private float radius;
 
    //화면에서 움직일 플레이어
    [SerializeField] private GameObject go_Player;
    //움직일 속도
    [SerializeField] private float moveSpeed;
 
    //터치가 시작됐을 때 움직이거라
    private bool isTouch = false;
    //움직일 좌표
    private Vector3 movePosition;
 
 
    void Start()
    {
        //inspector에 그 rect Transform에 접근하는 거 맞음
        //0.5를 곱해서 반지름을 구해서 값을 넣어줌
        this.radius = rect_Background.rect.width * 0.5f;
    }
 
    //이동 구현
    void Update()
    {
        if(this.isTouch)
        {
            this.go_Player.transform.position += this.movePosition;
        }
    }
 
 
 
    //인터페이스 구현
 
    //눌렀을 때(터치가 시작됐을 때)
    public void OnPointerDown(PointerEventData eventData)
    {
        this.isTouch = true;
    }
 
    //손 땠을 때
    public void OnPointerUp(PointerEventData eventData)
    {
        //손 땠을 때 원위치로 돌리기
        rect_Joystick.localPosition = Vector3.zero;
 
        this.isTouch = false;
        //움직이다 손을 놓았을 때 다시 클릭하면 방향 진행이 되는 현상을 고침
        this.movePosition = Vector3.zero;
    }
 
    //드래그 했을때
    public void OnDrag(PointerEventData eventData)
    {
        //마우스 포지션(x축, y축만 있어서 벡터2)
        //마우스 좌표에서 검은색 백그라운드 좌표값을 뺀 값만큼 조이스틱(흰 동그라미)를 움직일 거임
        Vector2 value =eventData.position - (Vector2)rect_Background.position;
 
        //가두기
        //벡터2인 자기자신의 값만큼, 최대 반지름만큼 가둘거임
        value = Vector2.ClampMagnitude(value, radius);
        //(1,4)값이 있으면 (-3 ~ 5)까지 가두기 함
 
        //부모객체(백그라운드) 기준으로 떨어질 상대적인 좌표값을 넣어줌
        rect_Joystick.localPosition = value;
 
        //value의 방향값만 구하기
        value = value.normalized;
        //x축에 방향에 속도 시간을 곱한 값
        //y축에 0, 점프 안할거라서
        //z축에 y방향에 속도 시간을 곱한 값
        this.movePosition = new Vector3(value.x * moveSpeed * Time.deltaTime, 
                                        0f, 
                                        value.y * moveSpeed * Time.deltaTime);
    }
}
 
 

 

 

 

 

 

2. 가속이 있을 경우

멀리 드래그 할 수록(백그라운드의 반지름값만큼 드래그할 수록) 빨라짐

중앙에 가까울 수록 느려짐

 

 

 

 

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems; //터치와 관련된 인터페이스를 가져올 거임
                                //마우스 클릭 시작했을 때  //마우스 손 땠을 때  //드래그 했을 때
public class Test : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
    //이 스크립트는 백그라운드에 어사인 해줌
    //터치에 반응할 부분은 백그라운드이기 때문
 
    //움직이는 범위를 제한하기 위해서 선언함
    [SerializeField] private RectTransform rect_Background;
    [SerializeField] private RectTransform rect_Joystick;
 
    //백그라운드의 반지름의 범위를 저장시킬 변수
    private float radius;
 
    //화면에서 움직일 플레이어
    [SerializeField] private GameObject go_Player;
    //움직일 속도
    [SerializeField] private float moveSpeed;
 
    //터치가 시작됐을 때 움직이거라
    private bool isTouch = false;
    //움직일 좌표
    private Vector3 movePosition;
 
 
    void Start()
    {
        //inspector에 그 rect Transform에 접근하는 거 맞음
        //0.5를 곱해서 반지름을 구해서 값을 넣어줌
        this.radius = rect_Background.rect.width * 0.5f;
    }
 
    //이동 구현
    void Update()
    {
        if(this.isTouch)
        {
            this.go_Player.transform.position += this.movePosition;
        }
    }
 
 
 
    //인터페이스 구현
 
    //눌렀을 때(터치가 시작됐을 때)
    public void OnPointerDown(PointerEventData eventData)
    {
        this.isTouch = true;
    }
 
    //손 땠을 때
    public void OnPointerUp(PointerEventData eventData)
    {
        //손 땠을 때 원위치로 돌리기
        rect_Joystick.localPosition = Vector3.zero;
 
        this.isTouch = false;
        //움직이다 손을 놓았을 때 다시 클릭하면 방향 진행이 되는 현상을 고침
        this.movePosition = Vector3.zero;
    }
 
    //드래그 했을때
    public void OnDrag(PointerEventData eventData)
    {
        //마우스 포지션(x축, y축만 있어서 벡터2)
        //마우스 좌표에서 검은색 백그라운드 좌표값을 뺀 값만큼 조이스틱(흰 동그라미)를 움직일 거임
        Vector2 value =eventData.position - (Vector2)rect_Background.position;
 
        //가두기
        //벡터2인 자기자신의 값만큼, 최대 반지름만큼 가둘거임
        value = Vector2.ClampMagnitude(value, radius);
        //(1,4)값이 있으면 (-3 ~ 5)까지 가두기 함
 
        //**거리에 따른 스피드를 다르게 하기
        //최대 스피드는 1 (최대 거리는 반지름만큼 나오게 되는데 반지름만큼 또 나누면 1이 최대값으로 나온다)
        float distance = Vector2.Distance(rect_Background.position, rect_Joystick.position) / this.radius;
 
        //부모객체(백그라운드) 기준으로 떨어질 상대적인 좌표값을 넣어줌
        rect_Joystick.localPosition = value;
 
        //value의 방향값만 구하기
        value = value.normalized;
        //x축에 방향에 속도 시간을 곱한 값
        //y축에 0, 점프 안할거라서
        //z축에 y방향에 속도 시간을 곱한 값
        this.movePosition = new Vector3(value.x * moveSpeed * distance* Time.deltaTime, 
                                        0f, 
                                        value.y * moveSpeed * distance* Time.deltaTime);
    }
}
 
 

 

 

 

출처