Делал игру 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();
}
}