본문 바로가기
PROGRAMING📚/Unity📑

[UNITY] 모바일 가상 조이스틱 구현하기(2)

별찌루 2023. 7. 20.
728x90
반응형

모바일 가상 조이스틱 구현하기(2)


 

[UNITY] 모바일 가상 조이스틱 구현하기(1)

모바일 가상 조이스틱 구현하기(1) 가상 조이스틱을 구현하기 위해서 젤 처음으로 UI를 디자인 해주었다 Joystick(하얀 동그라미) 이미지에 자식으로 Lever(파란색 동그라미) 로 구현하였다. 조이스

j2su0218.tistory.com

 

가상 조이스틱을 구현하기 2탄으로

1탄에서는 조이스틱과 레버를 이벤트 핸들러의 입력을 받아서

드래그 하는 곳으로 레버가 따라서 움직이도록 구현하였다.

 

이번에는 레버의 이동을 제한하는 것을 구현하려고 한다


Lever 이동 제한


Lever가 Joystick에서 벗어나지 않도록 하기 위해서는

Joystick의 중심에서 일정 범위 이상으로 넘어가지 않게 거리를 제한 해주어야 한다

 

나의 Lever는 120 을 넘어가면 안될 것 같아서

최대 120까지 범위를 주려고 한다

범위를 주기 위해서  leverRange 라는 float 변수를 하나 생성 해주었다

[SerializeField]private float leverRange =120f;

변수의 앞에 [SerializeField, Range(최소 범위 값, 최대 범위 값 )] 을 적어주면

    인스펙터 창에서 슬라이더 형식으로 디자인이 가능하다

 

드래그를 했을 때 일정 범위 안에서 동작하게 하기위해서

OnBegin()/OnDrag() 코드를 수정해주어야 한다

 

   var rangeDir = inputPos.magnitude < leverRange ? inputPos : inputPos.normalized * leverRange;

 

다음 코드를 이해야하기 위해서

magnitue에 대해서 알아야 하기 때문에 잘 정리 되어 있는 관련 참조 글을 가지고 왔다

 

 

[Unity3D] 벡터의 길이(크기)와 활용 / Vector3.magnitude

1. 벡터의 길이 (1) 벡터의 개념 벡터 : 크기와 방향을 갖는 물리량 스칼라 : 크기만을 갖는 물리량 벡터는...

blog.naver.com

유니티에서 벡터를 사용하는 이유는

두 좌표 사이의 거리를 구할때, 어떤 물체의 속도를 구할 때 사용된다

우리는 여기서 Lever가 Joystick 안에서 움직일 수 있는 거리의 범위를 구하기 위해서

 벡터의 길이를 알기위해서  Magnitude(벡터의 길이를 반환)를 사용 할 것이다.

 

코드를 분석해보면 삼항 연산자(?)를 사용해서 조건을 작성 해주었다

문법 : 조건식 ? 반환값1 : 반환값2

 

"만약에 Lever의 앵커(Lever Anchor)로 부터 피봇(Lever Pivot) 까지의 거리가 120보다 작으면

var rangeDir 에 var inputPos 값을 적용해주고 아니면 input.normalized * leverRange 값을 적용해라" 라는 의미

 

normalized 는 정규화를 의미하는데 inputPos를 정규화 하겠다는 말은

쉽게 설명하면 벡터의 동일한 방향을 가지지만 크기(길이)를 1로 한다는 의미를 가진다.

벡터가 너무 작은 경우는 0으로 설정된다. 

 

이렇게 코드를 작성해주고

Lever를 최대한 밖으로 끌었을 때

 

[OnBegin] 결과값

 

inputPos.magnitude : 20.94938
leverRange : 120
inputPos : (20.81, -2.40)
inputPos.normalized * leverRange : (119.21, -13.72)
rangeDir : (20.81, -2.40)

 

[OnDrag] 결과값

 

inputPos.magnitude : 211.6645
leverRange : 120
inputPos : (188.73, 95.82)
inputPos.normalized * leverRange : (107.00, 54.32)
rangeDir : (107.00, 54.32)

 

inputPos.magnitude의 값이 120보다 작을 때는 

rangeDir 값이 inputPos와 같지만

120 보다 커졌을 때 rangeDir 값이 input.normalized*leverRange의

값을 받고 있는 것을 볼 수 있다

 

 

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

public class VirtualJoystick : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
{
    [SerializeField]
    private RectTransform leverTransform;
    private RectTransform rectTransform;

    //[SerializeField, Range(10f, 120f)]
    [SerializeField] private float leverRange = 120f;

    private void Awake()
    {
        rectTransform = GetComponent<RectTransform>();
    }
    public void OnBeginDrag(PointerEventData eventData)
    {
        DragEvent(eventData);
    }
    public void OnDrag(PointerEventData eventData)
    {
        DragEvent(eventData);
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        leverTransform.anchoredPosition = Vector2.zero;
    }
    private void DragEvent(PointerEventData eventData)
    {
        var inputPos = eventData.position - rectTransform.anchoredPosition;
        var rangeDir = inputPos.magnitude < leverRange ? inputPos : inputPos.normalized * leverRange;
        leverTransform.anchoredPosition = rangeDir;

        Debug.Log("inputPos.magnitude : " + inputPos.magnitude
+ "\nleverRange : " + leverRange
+ "\ninputPos : " + inputPos
+ "\ninputPos.normalized * leverRange : " + inputPos.normalized * leverRange
+ "\nrangeDir : " + rangeDir
);

    }
}
728x90
반응형

댓글