유니티에서 Input System을 활용하여 터치 이벤트를 받아서 활용하는 법을 남겨본다.
Input Action 생성



InputController.cs 작성
using UnityEngine;
using UnityEngine.InputSystem;
[DefaultExecutionOrder(-1)]
public class InputController : InitBase
{
public delegate void StartTouch(Vector2 position, float time);
public event StartTouch OnStartTouchEvent;
public delegate void EndTouch(Vector2 position, float time);
public event EndTouch OnEndTouchEvent;
private PlayerControls playerControls;
private Camera mainCamera;
protected override bool Init()
{
if (base.Init() == false)
return false;
playerControls = new PlayerControls();
mainCamera = Camera.main;
return true;
}
private void OnEnable()
{
playerControls.Enable();
}
private void OnDisable()
{
playerControls.Disable();
}
private void Start()
{
playerControls.Touch.PrimaryContact.started += ctx => OnTouchPrimaryContactStarted(ctx);
playerControls.Touch.PrimaryContact.canceled += ctx => OnTouchPrimaryContactEnded(ctx);
}
private void OnTouchPrimaryContactStarted(InputAction.CallbackContext ctx)
{
OnStartTouchEvent?.Invoke(
Utils.ScreenToWorld(
mainCamera,
playerControls.Touch.PrimaryPosition.ReadValue<Vector2>()
),
(float)ctx.startTime
);
}
private void OnTouchPrimaryContactEnded(InputAction.CallbackContext ctx)
{
OnEndTouchEvent?.Invoke(
Utils.ScreenToWorld(
mainCamera,
playerControls.Touch.PrimaryPosition.ReadValue<Vector2>()
),
(float)ctx.time
);
}
public Vector2 PrimaryPosition()
{
return Utils.ScreenToWorld(mainCamera, playerControls.Touch.PrimaryPosition.ReadValue<Vector2>());
}
}
using System.Collections;
using UnityEngine;
public class SwipeDetection : MonoBehaviour
{
[SerializeField] private float minimumSwipeDistance = 0.2f;
[SerializeField] private float maximumSwipeTime = 1f;
[SerializeField] private float directionThreshold = 0.9f;
[SerializeField] private GameObject trail;
private InputController inputController;
private Vector2 startPosition;
private float startTime;
private Vector2 endPosition;
private float endTime;
private Coroutine coroutine;
private void Awake()
{
inputController = gameObject.GetOrAddComponent<InputController>();
}
private void OnEnable()
{
inputController.OnStartTouchEvent += SwipeStart;
inputController.OnEndTouchEvent += SwipeEnd;
}
private void OnDisable()
{
inputController.OnStartTouchEvent -= SwipeStart;
inputController.OnEndTouchEvent -= SwipeEnd;
}
private void SwipeStart(Vector2 position, float time)
{
startPosition = position;
startTime = time;
trail.transform.position = position;
trail.SetActive(true);
coroutine = StartCoroutine(Trail());
}
private IEnumerator Trail()
{
while (true)
{
trail.transform.position = inputController.PrimaryPosition();
yield return null;
}
}
private void SwipeEnd(Vector2 position, float time)
{
trail.SetActive(false);
StopCoroutine(coroutine);
endPosition = position;
endTime = time;
DetectSwipe();
}
private void DetectSwipe()
{
if (Vector3.Distance(startPosition, endPosition) >= minimumSwipeDistance &&
(endTime - startTime) <= maximumSwipeTime)
{
Debug.Log("Swipe Detected");
Debug.DrawLine(startPosition, endPosition, Color.red, 5f);
Vector3 direction = endPosition - startPosition;
Vector2 direction2D = new Vector2(direction.x, direction.y).normalized;
SwipeDirection(direction2D);
}
}
private void SwipeDirection(Vector2 direction)
{
if (Vector2.Dot(Vector2.up, direction) > directionThreshold)
{
Debug.Log("Swipe Up");
}
else if (Vector2.Dot(Vector2.down, direction) > directionThreshold)
{
Debug.Log("Swipe Down");
}
else if (Vector2.Dot(Vector2.left, direction) > directionThreshold)
{
Debug.Log("Swipe Left");
}
else if (Vector2.Dot(Vector2.right, direction) > directionThreshold)
{
Debug.Log("Swipe Right");
}
}
}
Component 달아주고, Trail도 하나 만들어서 넣어주면 된다.

결과물

여기에다가 아무 방향으로 스와이프를 해주면 스와이프를 인식할 수 있다.
