Unity3d

[Sirion] 조이스틱 관련 코드

Sirion 2021. 11. 25. 14:41

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


public class JoystickController : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
    [Header("Joystick")]
    [SerializeField] private RectTransform rect_bg;     //joystick 배경
    [SerializeField] private RectTransform rect_stick;      //joystick의 stick
    private bool touch_check = false;   // joystick 눌렸는지 확인
    [SerializeField] private float radius;  //joystick 반지름

    [Header("target")]
    [SerializeField] private GameObject target; //움직일 target
    [SerializeField] private float speed;   //target의 속도
    private Vector3 targetMove;  //target의 위치

    [Header("Joy_Move")]
    [SerializeField] private bool jostick_move_check = false;   //true : 순간이동 joystick, false : 고정 joystick
    [SerializeField] private GameObject touch_range;    //터치 허용범위 이미지

    #region UnityFuction

    private void Start()
    {
        //조이스틱 활성화 할지말지
        rect_bg.gameObject.SetActive(!jostick_move_check);
        touch_range.SetActive(jostick_move_check);

        //반지름 구하기
        radius = rect_bg.rect.width * 0.5f;
    }

    #endregion

    #region Mover    

    private void JoyStickOnTouch(Vector2 pos)
    {
        Vector2 vec = new Vector2(pos.x - rect_bg.position.x, pos.y - rect_bg.position.y);

        // 거리제한(반지름 이상 나갈수 없도록)
        vec = Vector2.ClampMagnitude(vec, radius);
        rect_stick.localPosition = vec;

        // 비율
        float fSqr = (rect_bg.position - rect_stick.position).sqrMagnitude / (radius * radius);

        // 터치 정규화
        Vector2 vecNormal = vec.normalized;
        //3d
        targetMove = new Vector3(vecNormal.x * speed * Time.deltaTime * fSqr, 0f, vecNormal.y * speed * Time.deltaTime * fSqr);
        //2d
        //targetMove = new Vector3(vecNormal.x * speed * Time.deltaTime * fSqr, vecNormal.y * speed * Time.deltaTime * fSqr, 0f);

        //방향
        target.transform.eulerAngles = new Vector3(0f, Mathf.Atan2(vecNormal.x, vecNormal.y) * Mathf.Rad2Deg, 0f);
    }

    #endregion

    #region OnPointer - Controller    

    public void OnDrag(PointerEventData eventData)
    {
        touch_check = true;
        JoyStickOnTouch(eventData.position);
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        //true : 순간이동 joystick, false : 고정 joystick
        if (jostick_move_check)
        {
            rect_bg.gameObject.SetActive(true);
            rect_bg.position = eventData.position;
        }

        touch_check = true;
        JoyStickOnTouch(eventData.position);

        StartMoverCourutine();
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        //true : 순간이동 joystick, false : 고정 joystick
        if (jostick_move_check)
            rect_bg.gameObject.SetActive(false);

        touch_check = false;
        rect_stick.localPosition = Vector3.zero;

        StopMoverCourutine();
    }

    #endregion

    #region Courutine

    private IEnumerator courutine_mover;
    private IEnumerator MoverCourutine()
    {
        while (true)
        {
            yield return null;

            if (touch_check)
                target.transform.position += targetMove;
        }
    }

    private void StartMoverCourutine()
    {
        courutine_mover = MoverCourutine();
        StartCoroutine(courutine_mover);
    }

    private void StopMoverCourutine()
    {
        StopCoroutine(courutine_mover);

        if (courutine_mover != null)
            courutine_mover = null;
    }

    #endregion

}

 

조이스틱 구성