본문 바로가기
게임 개발

유니티 조이스틱 구현하여 캐릭터 조종하기!

by 오리의테크 2022. 1. 21.
728x90
반응형

 

1. 조이스틱 스크립트 예시1

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);
    }
}
2. 조이스틱 스크립트 예시2

1.using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class Joy_Stick : MonoBehaviour
{

    // 공개


    public Vector3 moveDirection;
    public Transform Stick;         // 조이스틱.


    public float Speed;

    // 비공개
    private Vector3 StickFirstPos;  // 조이스틱의 처음 위치.
    public Vector3 JoyVec;         // 조이스틱의 벡터(방향)
    private float Radius;           // 조이스틱 배경의 반 지름.
    public bool MoveFlag;          // 플레이어 움직임 스위치.


    private void Awake()
    {
        
    }
    void Start()
    {
     

        Radius = GetComponent<RectTransform>().sizeDelta.y * 0.5f;
        StickFirstPos = Stick.transform.position;

        // 캔버스 크기에대한 반지름 조절.
        float Can = transform.parent.GetComponent<RectTransform>().localScale.x;
        Radius *= Can;

        MoveFlag = false;
    }

    void Update()
    {
        
    }
    // 드래그
    public void Drag(BaseEventData _Data)
    {
        MoveFlag = true;
        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;



        //Player.transform.eulerAngles = new Vector3(0, Mathf.Atan2(JoyVec.x, JoyVec.y) * Mathf.Rad2Deg, 0);
        //Player.transform.eulerAngles = new Vector3(0, 90 , 0);
        //if (Mathf.Atan2(JoyVec.x, JoyVec.y) * Mathf.Rad2Deg>45&& Mathf.Atan2(JoyVec.x, JoyVec.y) * Mathf.Rad2Deg < 135)
        //{

        //}
        //if (Mathf.Atan2(JoyVec.x, JoyVec.y) * Mathf.Rad2Deg > -90 && Mathf.Atan2(JoyVec.x, JoyVec.y) * Mathf.Rad2Deg < 45)
        //{
        //    Player.transform.eulerAngles = new Vector3(0, 45, 0);
        //}
        //if (Mathf.Atan2(JoyVec.x, JoyVec.y) * Mathf.Rad2Deg < -90 && Mathf.Atan2(JoyVec.x, JoyVec.y) * Mathf.Rad2Deg > 120)
        //{
        //    Player.transform.eulerAngles = new Vector3(0, 135, 0);
        //}
    }

    // 드래그 끝.
    public void DragEnd()
    {
      

        Stick.position = StickFirstPos; // 스틱을 원래의 위치로.
        JoyVec = Vector3.zero;          // 방향을 0으로.
        MoveFlag = false;
    }
}

728x90
반응형

댓글