본문 바로가기
App && Game

[유니티] 화면 드래그(스와이프/터치)에 따른 오브젝트 회전

by 배애앰이 좋아 2023. 4. 17.
반응형

 

이번 글에는 게임 만들다가 나중에 또 쓸 거 같은 기능들 정리하고자 합니다. 화면 드래그(스와이프/터치)에 따른 오브젝트 회전하는 기능으로 보통 360도 물체를 보고 싶을 때 주로 사용하는 기능인 것 같습니다.

 

구현 결과 :

 

 

안드로이드 상에서 손가락으로 드래그할 때 장면이라 마우스가 표시되지는 않지만 현재 오른쪽으로 스와이프 하면 물체가 오른쪽 방향으로 회전 / 위로 스와이프하면 위로 회전 등 상하좌우 스와이프 방향에 따라 물체가 맞게 회전할 수 있도록 구현하였습니다.

 

다음과 같은 코드를 사용했습니다.

 

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

public class TouchManager : MonoBehaviour
{
    public GameObject answerObj; // 회전할 오브젝트 1
    public GameObject wrongObj; // 회전할 오브젝트 2
    private Vector2 touchBeganPos;
    private Vector2 touchEndedPos;
    private Vector2 touchDif;
    private float swipeSensitivity = 15; // 터치 민감도
    private float checkTime = 1; // 다음 터치될 때까지 걸리는 시간
    private float currentTime = 0;
    private float RoSpeedTime = 0;

    // Start is called before the first frame update
    void Start()
    {
        RoSpeedTime = 60 / checkTime;
    }

    // Update is called once per frame
    void Update()
    {
        Swipe();
        currentTime += Time.deltaTime;
    }

    IEnumerator Turn(float duration, Vector3 vector)
    {
        var runTime = 0.0f;

        while (runTime < duration)
        {
            runTime += Time.deltaTime;
            answerObj.transform.Rotate(vector * Time.deltaTime * RoSpeedTime, Space.World);
            wrongObj.transform.Rotate(vector * Time.deltaTime * RoSpeedTime, Space.World);
            yield return null;
        }
    }

    IEnumerator Wait(float duration, Vector3 vector)
    {
        yield return StartCoroutine(Turn(duration, vector));
    }

    //스와이프와 터치
    public void Swipe()
    {
        if (Input.touchCount > 0 && currentTime > checkTime)
        {
            Touch touch = Input.GetTouch(0);
            if (touch.phase == TouchPhase.Began)
            {
                touchBeganPos = touch.position;
            }
            if (touch.phase == TouchPhase.Ended)
            {
                touchEndedPos = touch.position;
                touchDif = (touchEndedPos - touchBeganPos);

                //스와이프. 터치의 x이동거리나 y이동거리가 민감도보다 크면
                if (Mathf.Abs(touchDif.y) > swipeSensitivity || Mathf.Abs(touchDif.x) > swipeSensitivity)
                {
                    if (touchDif.y > 0 && Mathf.Abs(touchDif.y) > Mathf.Abs(touchDif.x))
                    {
                        Debug.Log("up");
                        StartCoroutine(Wait(1f, new Vector3(1, 0, 0)));
                    }
                    else if (touchDif.y < 0 && Mathf.Abs(touchDif.y) > Mathf.Abs(touchDif.x))
                    {
                        Debug.Log("down");
                        StartCoroutine(Wait(1f, new Vector3(-1, 0, 0)));
                    }
                    else if (touchDif.x > 0 && Mathf.Abs(touchDif.y) < Mathf.Abs(touchDif.x))
                    {
                        Debug.Log("right");
                        StartCoroutine(Wait(1f, new Vector3(0, -1, 0)));
                    }
                    else if (touchDif.x < 0 && Mathf.Abs(touchDif.y) < Mathf.Abs(touchDif.x))
                    {
                        Debug.Log("Left");
                        StartCoroutine(Wait(1f, new Vector3(0, 1, 0)));
                    }
                    currentTime = 0;
                }
                //터치
                else
                {
                    Debug.Log("touch");
                    currentTime = 0;
                }
            }
        }
    }
    
}

 

위에서 checkTime 같은 경우 스와이프하고 잠시 터치되는 것을 막아주는 역할로 만약에 없다면 돌아가는 중에 다른 회전 명령어가 실행되어 x, y 축이 한번에 움직여서 대각선으로 돌아가는 결과가 나올 수도 있습니다. 물론 원하는 조건에 따라 쓰이거나 필요할 수 있지만 저 같은 경우 x 든 y 든 한 축에 고정해서 움직이는 것을 원하기 때문에 위에처럼 구현하였습니다. 

반응형

댓글