게임클라이언트 프로그래밍/R&D

2D Joystick을 이용한 이동 구현

Game Client Lee Hwanguk 2023. 2. 26. 18:53

#조이스틱 구현

#IBeginDragHandler,IDragHandler,IEndDragHandler 인터페이스를 이용하여 드레그 이벤트 생성

#조이스틱의 이동 제한(stick이 bg를 벗어나지 않게)

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


public class joystick : MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler // 인터페이스 추가(ctrl . ->메서드 자동구현)
{
    [SerializeField]
    private RectTransform lever; //stick
    private RectTransform rectTransform; //bg

    [SerializeField, Range(10, 150)]
    private float leverRange; //lever 이동 거리 제한

    private Vector2 inputDirection; //player의 이동값
    private bool isInput; //bool값으로 joystick제어 (onDrag에서는 클릭을 유지해도 마우스 이동이없다면 동작 X)

    //player이동
    public GameObject player;
    private float playerSpeed = 600f; //player의 이동속도 제한
    private void Awake()
    {
        this.rectTransform=GetComponent<RectTransform>();
    }
    public void OnBeginDrag(PointerEventData eventData) //드레그 시작
    {
        ControlJoysitckLever(eventData);
        isInput= true;
    }

    public void OnDrag(PointerEventData eventData) //드레그 중
    {
        ControlJoysitckLever(eventData);
        //오브잭트를 클랙해서 드래그 하는 도중에 들어오는 이벤트
        //클릭을 유지한 상태로 마우스 이동을 멈추면 이벤트 X
    }

    public void OnEndDrag(PointerEventData eventData) //드레그 끝
    {
        //throw new System.NotImplementedException();
        lever.anchoredPosition = Vector2.zero; //드레그가 끝나면 0,0으로 돌아감
        isInput= false;
        //Debug.Log("End");
    }

    private void ControlJoysitckLever(PointerEventData eventData)
    {
        var inputPos = eventData.position - rectTransform.anchoredPosition; //eventData의 포지션-터치한 포지션 -bg의 앵커포지션
        var inputVector = inputPos.magnitude < leverRange ? inputPos : inputPos.normalized * leverRange; // true ? false(조건연산자)
        //inputPos의 거리(magitude) 가 leverRange보다 작다면
        lever.anchoredPosition = inputVector;
        inputDirection = inputVector / playerSpeed; //player의 이동값 제한

    }
    private void InputControlVector()
    {
        //Debug.Log(inputDirection.x + "/" + inputDirection.y);
        this.player.GetComponent<CharacterController>().Move(this.inputDirection); //CharacterController의 Move 메서드
    }



    //joystick의 vector2 값을 plyer의 이동값으로 ->player의 이동
    void Update()
    {
        if(isInput)
        {
            InputControlVector();
        }
    }
}

 

#Character Controller의 컴포넌트 Move를 사용하여 이동해보았다

 

#조이스틱의 배경화면(bg)인 rectTransform의 RectTransform를 컴포넌트로 가져온 후 enentData의 position에서 값을 빼준다 =>eventData.position - rectTransform.anchoredPosition;

 

#조건부연산자

변수 = 조건부 ? trut : false;

#inputPos.magnitude < leverRange ?(=>조건) // input.Pos(true) : inputPos.normalized * leverRange(false)(조건qn연산자)