@yraiv

Почему игра на телефоне видит свайпы через раз?

Делал игру 2048. Игра под Webgl, столкнулся с проблемой, что при свайпе на компе всё происходит корректно, но если свайп на телефоне, то он может работать через раз. Зависимость никакую не нашёл (длина свайпа, скорость свайпа и тд). В чем может быть причина?
(не реклама, может поможет понять в чем беда)


using UnityEngine;

public class SwipeDetection : MonoBehaviour
{

    public static event OnSwipeInput SwipeEvent;
    public delegate void OnSwipeInput(Vector2 direction);

    private Vector2 tapPosition;
    private Vector2 swipeDelta;
    [SerializeField]
    private float deadZone = 8;
    private bool isSwiping;
    private bool isMobile;

    private void Start()
    {
        isMobile = Application.isMobilePlatform;
        
    }

    private void Update()
    {
        if (!isMobile)
        {
            if (Input.GetMouseButtonDown(0))
            {
                isSwiping = true;
                tapPosition = Input.mousePosition;
            }
            else if (Input.GetMouseButtonUp(0))
                ResetSwipe();
        }
        else
        {
            if(Input.touchCount > 0)
            {
                if(Input.GetTouch(0).phase == TouchPhase.Began)
                {
                    isSwiping = true;
                    tapPosition = Input.GetTouch(0).position;

                }
                else if(Input.GetTouch(0).phase == TouchPhase.Canceled||
                    Input.GetTouch(0).phase == TouchPhase.Ended)
                {
                    ResetSwipe();
                }
            }
        }
        CheckSwipe();
    }

    private void CheckSwipe()
    {
        swipeDelta = Vector2.zero;
        if (isSwiping)
        {
            if(!isMobile && Input.GetMouseButton(0))
                swipeDelta = (Vector2)Input.mousePosition - tapPosition;
                else if (Input.touchCount > 0)
                    swipeDelta = Input.GetTouch(0).position - tapPosition;

            


        }
        if( swipeDelta.magnitude > deadZone)
        {
            if (Mathf.Abs(swipeDelta.x) > Mathf.Abs(swipeDelta.y))
                SwipeEvent?.Invoke(swipeDelta.x > 0 ? Vector2.right : Vector2.left);
            else
                SwipeEvent?.Invoke(swipeDelta.y > 0 ? Vector2.up : Vector2.down);
            ResetSwipe();

        }

    }

    private void ResetSwipe()
    {
        isSwiping = false;
        tapPosition = Vector2.zero;
        swipeDelta = Vector2.zero;

    }


}

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

public class Field : MonoBehaviour
{

    public static Field Instance;

    [Header("Настройки поля")]
    public float CellSize;
    public float Spacing;
    public int FieldSize;
    public int IntCellsCount;

    [Space(10)]
    [SerializeField]
    private Cell cellPref;
    [SerializeField]
    private RectTransform rt;
    private bool anyCellMoved;
    private Cell[,] field;

    private void Awake()
    {
        if (Instance == null)
            Instance = this;
    }

    private void Start()
    {
        SwipeDetection.SwipeEvent += OnInput;

    }
  

    private void OnInput(Vector2 direction)
    {
        if (!GameController.GameStarted)
            return;

        anyCellMoved = false;
        ResetCellsFlags();

        Move(direction);
        if (anyCellMoved)
        {
            GenerateRandomCell();
            CheckGameResult();
        }
    }

    private void Move(Vector2 direction)
    {
        int startXY = direction.x > 0 || direction.y < 0 ? FieldSize - 1 : 0;
        int dir = direction.x != 0 ? (int)direction.x : -(int)direction.y;

        for (int i = 0; i < FieldSize; i++)
        {
            for (int k = startXY; k >= 0 && k < FieldSize; k -= dir)
            {
                var cell = direction.x != 0 ? field[k, i] : field[i, k];

                if (cell.IsEmpty)
                    continue;
                var cellToMerge = FindCellToMerge(cell, direction);
                if(cellToMerge!= null)
                {
                    cell.MergeWithCell(cellToMerge);
                    anyCellMoved = true;

                    continue;
                }

                var emptyCell = FindEmptyCell(cell, direction);
                 if (emptyCell != null)
                {
                    cell.MoveToCell(emptyCell);
                    anyCellMoved = true;
                }
            }

        }
    }


    private Cell FindCellToMerge(Cell cell, Vector2 direction)
    {
        int StartX = cell.X + (int)direction.x;
        int StartY = cell.Y - (int)direction.y;

        for (int x = StartX, y = StartY ;
        x >= 0 && x < FieldSize && y >= 0 && y < FieldSize;
        x += (int)direction.x, y -= (int)direction.y)
        {
            if (field[x, y].IsEmpty)
                continue;

            if (field[x, y].Value == cell.Value && !field[x, y].HasMerged)
                return field[x, y];
            break;

        }
        return null;
        
    }

    private Cell FindEmptyCell(Cell cell, Vector2 direction)
    {
        Cell emptyCell = null;
        int startX = cell.X + (int)direction.x;
        int startY = cell.Y - (int)direction.y;


        for (int x = startX, y = startY;
            x >= 0 && x < FieldSize && y >= 0 && y < FieldSize;
            x += (int)direction.x, y -= (int)direction.y)
        {
            if (field[x, y].IsEmpty)
                emptyCell = field[x, y];
            else
                break;
        }
        return emptyCell;
       
    }

    private void CheckGameResult()
    {
        bool lose = true;
        for (int x = 0; x < FieldSize; x++)
        {
            for(int y = 0; y < FieldSize; y++)
            {
                if(field[x,y].Value == Cell.MaxValue)
                {
                    GameController.Instance.Win();
                    return;
                } 
                if( lose &&
                    field[x,y].IsEmpty ||
                    FindCellToMerge(field[x,y],Vector2.left) ||
                    FindCellToMerge(field[x, y], Vector2.right) ||
                    FindCellToMerge(field[x, y], Vector2.up) ||
                    FindCellToMerge(field[x, y], Vector2.down))
                {
                    lose = false;
                }

            }
        }

        if (lose)
            GameController.Instance.Lose();
    }
    public void CreateField()
    {
        field = new Cell[FieldSize, FieldSize];
        float fieldWith = FieldSize * (CellSize + Spacing) + Spacing;
        rt.sizeDelta = new Vector2(fieldWith, fieldWith);


        float StartX = -(fieldWith / 2) + (CellSize / 2) + Spacing;
        float StartY = (fieldWith / 2) - (CellSize / 2) + Spacing;

        for (int x = 0; x < FieldSize; x++)
        {
            for (int y = 0; y <FieldSize; y++)
            {
                var cell = Instantiate(cellPref, transform, false);
                var position = new Vector2(StartX + (x * (CellSize + Spacing)), StartY - (y * (CellSize + Spacing)));
                cell.transform.localPosition = position;
                field[x, y] = cell;
                cell.SetValue(x, y, 0);
            }
        }
    }


    public void GenerateField()
    {
        if (field == null)
            CreateField();

        for (int x = 0; x < FieldSize; x++)
            for (int y = 0; y < FieldSize; y++)
                field[x, y].SetValue(x, y, 0);

        for (int i = 0; i < IntCellsCount; i++)
            GenerateRandomCell();
    }





    public void GenerateRandomCell()
    {
        var emptyCells = new List<Cell>();
        for (int x = 0; x < FieldSize; x++)
            for (int y = 0; y < FieldSize; y++)
                if (field[x, y].IsEmpty)
                    emptyCells.Add(field[x, y]);

        if(emptyCells.Count == 0)
        {
            throw new System.Exception("Ошибочка 1");


        }

        int value = Random.Range(0, 10) == 0 ? 2 : 1;

        var cell = emptyCells[Random.Range(0, emptyCells.Count)];

        cell.SetValue(cell.X, cell.Y, value, false);


        CellAnimationContoller.Instance.SmoothAppear(cell);
    }

    private void ResetCellsFlags()
    {
        for (int x = 0; x < FieldSize; x++)
            for (int y = 0; y < FieldSize; y++)
                field[x, y].ResetFlags();

    }
}
  • Вопрос задан
  • 75 просмотров
Решения вопроса 1
freeExec
@freeExec
Участник OpenStreetMap
Обложите свой код дебажными сообщениями, и тогда будете понимать, куда при свайпе код завернул и где не выполнился.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы