Касание медленное при проверке области касания - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть скрипт TouchDragDrop.cs, который позволяет мне трогать и перетаскивать объект в 2D-пространстве.

Две функции, которые я хочу показать:

void Update()
{
    if (Input.touchCount > 0)
    {
        Touch touch = Input.GetTouch(0);
        // touchPosition = touch.position; 
        touchPosition = Camera.main.ScreenToWorldPoint(touch.position);

        switch (touch.phase)
        {
            case TouchPhase.Began: beginTouchMove();  break;
            case TouchPhase.Moved: moveTouch();  break;
            case TouchPhase.Stationary: stationaryTouch(); break;
            case TouchPhase.Ended: endTouchMove();  break;
        }

    }
}

private void moveTouch()
{
    //if ((myCollider2D == Physics2D.OverlapPoint(touchPosition)) && (isMoving))
    if(isMoving)
    {
        Vector2 newPosition = new Vector2(touchPosition.x - deltaX, touchPosition.y - deltaY);
        //gameObject.transform.position = newPosition;
        myRigidbody2D.MovePosition(newPosition);
        //if(debuglog) Debug.Log("Touch Position:  x: " + touchPosition.x.ToString() + " y: " + touchPosition.y.ToString());
        //if(debuglog) Debug.Log("RigidBody: " + myRigidbody2D.position.ToString());
    }
}

Теперь Для точного перемещения объекта мне нужно убедиться, что касание находится сверху объекта, поэтому у меня изначально была линия:

if ((myCollider2D == Physics2D.OverlapPoint(touchPosition)) && (isMoving))

Но это замедляет приложение настолько, что перетаскивание это тяжелая работа, как будто мне действительно нужно медленно нажимать и перетаскивать, чтобы персонаж двигался со мной. Так что, если я достану его и просто наберу if(isMoving), он снова будет быстрым.

Как я могу убедиться, что перетаскиваю только объект, а не только часть экрана?

1 Ответ

1 голос
/ 25 февраля 2020

Я могу только предположить, что у вас есть много объектов, запускающих этот скрипт, что и является причиной ваших проблем. Чтобы убедиться в этом, попробуйте уменьшить количество объектов, имеющих компонент TouchDragDrop , до 1 или 2 объектов. Вы, вероятно, заметите, что игра больше не замедляется.

Каждый раз, когда вы касаетесь экрана, все объекты с прикрепленным скриптом TouchDragDrop.cs читают ввод, а затем выполняют свою логику moveTouch. c. Если у вас есть 50 объектов с TouchDragDrop.cs , вы выполните Physics2D.OverlapPoint 50 раз. Это то, что может убить вашу производительность.

Physics2D.OverlapPoint следует вызывать только один раз. Если многие объекты должны реагировать на ваше прикосновение, рассмотрите возможность перемещения ввода и касания logi c к одному объекту gameObject, который отвечает только за чтение ввода и возврат того, какой коллайдер попал. Затем перенесите свою «логику движения c» в другой скрипт (возможно, он называется Draggable.cs ). Вместо того, чтобы сравнивать каждый GameObject, вы можете сделать следующее из этого единственного входного скрипта:

touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
Collider2D touchedCollider = Physics2D.OverlapPoint(touchPosition)
Draggable dragObj = touchedCollider?.GetComponent<Draggable>();
dragObj?.MoveTouch(touchPosition);

Обновление

Поскольку проблема не связана с количеством объектов GameObject в настоящее время, скорее всего, это связано с конфликтом между циклом Fixed и циклом Frame. Я написал довольно длинное объяснение различий между 2 , но вкратце я считаю, что это может быть вашей проблемой:

Когда вы читаете входные данные каждый кадр во время движения, положение коллайдера вашего физического объекта не обновляется немедленно. Обновляется только в фиксированном цикле, что означает, что у вашего входа есть небольшой шанс выйти за пределы коллайдера.

Вот новое решение:

Вместо подтверждения того, что вы касаетесь объекта в каждом кадре, давайте предположим, что вам нужно проверять позицию касания только один раз (во время Touc hPhase.Began). Я рекомендую что-то вроде этого:

void BeginTouchMove()
{
    if(myCollider2D == Physics2D.OverlapPoint(touchPosition))
    {
        isMoving = true;
    }
}

Тогда вы можете оставить свой MoveTouch () logi c таким же, как у вас выше, только с проверкой (isMoving).

...