void SetupField()     // стартовые установки, подготовка игрового поля
    {
        position  = new Vector3[gridWidth, gridHeight];
        nodeArray = new Match3Node[gridWidth * gridHeight];

        int i    = 0;
        int id   = -1;
        int step = 0;

        for (int y = 0; y < gridHeight; y++)
        {
            for (int x = 0; x < gridWidth; x++)
            {
                int j = Random.Range(0, Sprites.Length);

                if (id != j)
                {
                    id = j;
                }
                else
                {
                    step++;
                }

                if (step > 2)
                {
                    step = 0;
                    id   = (id + 1 < Sprites.Length - 1) ? id + 1 : id - 1;
                }

                grid[x, y].ready = false;

                grid[x, y].x = x;

                grid[x, y].y = y;

                grid[x, y].id = id;

                grid[x, y].sprite.sprite = Sprites[id];

                grid[x, y].gameObject.SetActive(true);

                grid[x, y].highlight.SetActive(false);

                position[x, y] = grid[x, y].transform.position;

                nodeArray[i] = grid[x, y];

                i++;
            }
        }

        current = null;
        last    = null;
    }
    bool CheckNearNodes(Match3Node node)     // проверка, возможно-ли совпадение на текущем ходу
    {
        if (node.x - 2 >= 0)
        {
            if (grid[node.x - 1, node.y].id == node.id && grid[node.x - 2, node.y].id == node.id)
            {
                return(true);
            }
        }

        if (node.y - 2 >= 0)
        {
            if (grid[node.x, node.y - 1].id == node.id && grid[node.x, node.y - 2].id == node.id)
            {
                return(true);
            }
        }

        if (node.x + 2 < gridWidth)
        {
            if (grid[node.x + 1, node.y].id == node.id && grid[node.x + 2, node.y].id == node.id)
            {
                return(true);
            }
        }

        if (node.y + 2 < gridHeight)
        {
            if (grid[node.x, node.y + 1].id == node.id && grid[node.x, node.y + 2].id == node.id)
            {
                return(true);
            }
        }

        if (node.x - 1 >= 0 && node.x + 1 < gridWidth)
        {
            if (grid[node.x - 1, node.y].id == node.id && grid[node.x + 1, node.y].id == node.id)
            {
                return(true);
            }
        }

        if (node.y - 1 >= 0 && node.y + 1 < gridHeight)
        {
            if (grid[node.x, node.y - 1].id == node.id && grid[node.x, node.y + 1].id == node.id)
            {
                return(true);
            }
        }

        return(false);
    }
    void Control()     // управление ЛКМ
    {
        if (Input.GetMouseButtonDown(0) && !isMode)
        {
            var hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, Mathf.Infinity, layerMask);

            if (hit.transform != null && current == null)
            {
                current = hit.transform.GetComponent <Match3Node>();
                SetNode(current, true);
                current.highlight.SetActive(true);
            }
            else if (hit.transform != null && current != null)
            {
                Effector.Instance.CreateChangeFromTo(current.transform.position, hit.transform.position);

                last = hit.transform.GetComponent <Match3Node>();

                if (last != null && !last.ready)
                {
                    current.highlight.SetActive(false);
                    last.highlight.SetActive(true);
                    SetNode(current, false);
                    SetNode(last, true);
                    current = last;
                    last    = null;
                    return;
                }

                // TODO: SWAP SOUND

                current.highlight.SetActive(false);
                currentPos = current.transform.position;
                lastPos    = last.transform.position;
                isMode     = true;
            }
        }
    }
    void MoveCurrent()     // перемещение выделенного мышкой узла
    {
        current.transform.position = Vector3.MoveTowards(current.transform.position, lastPos, speed * Time.deltaTime);

        last.transform.position = Vector3.MoveTowards(last.transform.position, currentPos, speed * Time.deltaTime);

        if (current.transform.position == lastPos && last.transform.position == currentPos)
        {
            GridUpdate();

            if (mode == Mode.MatchOnly && isMode && !CheckNearNodes(current) && !CheckNearNodes(last))
            {
                SoundManage.Instance.Error();

                currentPos = position[current.x, current.y];

                lastPos = position[last.x, last.y];

                isMode = false;

                return;
            }
            else
            {
                isMode = false;
            }

            current = null;
            last    = null;

            if (IsLine())
            {
                timeout = 0;
                isLines = true;
            }
        }
    }
    void SetNode(Match3Node node, bool value)     // метка для узлов, которые находятся рядом с выбранным (чтобы нельзя было выбрать другие)
    {
        if (node == null)
        {
            return;
        }

        if (node.x - 1 >= 0)
        {
            grid[node.x - 1, node.y].ready = value;
        }
        if (node.y - 1 >= 0)
        {
            grid[node.x, node.y - 1].ready = value;
        }
        if (node.x + 1 < gridWidth)
        {
            grid[node.x + 1, node.y].ready = value;
        }
        if (node.y + 1 < gridHeight)
        {
            grid[node.x, node.y + 1].ready = value;
        }
    }