Перетаскивание объекта с помощью Raycast является медленным - PullRequest
0 голосов
/ 03 июня 2019

При медленном перетаскивании объекта с помощью raycast объект перемещается с небольшим запаздыванием.

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

Основной проект - перетаскивание куба на плоскость.

Но чтобы упростить проект, я открыл новый 2D-проект, сделал круг и назначил ему следующий скрипти прикрепил к нему коллайдер сфер (основная цель находится в трехмерном пространстве).

// If some one wrote:
private Vector2 deltaPos;
    void Update () {
        Vector2 touchPos;
        if (Input.GetMouseButtonDown (0)) {                                                     // Clicking the Target              
            RaycastHit hit;
            var ray = Camera.main.ScreenPointToRay (Input.mousePosition);

            if (Physics.Raycast (ray, out hit, Mathf.Infinity)) {

                touchPos = new Vector3 (hit.point.x, hit.point.y);
                deltaPos.x = touchPos.x - transform.position.x;
                deltaPos.y = touchPos.y - transform.position.y;
                Debug.Log ("You Clicked Me");
            }
        }
        if (Input.GetMouseButton (0)) {
            RaycastHit hit;
            var ray = Camera.main.ScreenPointToRay (Input.mousePosition);

            if (Physics.Raycast (ray, out hit, Mathf.Infinity)) {
                transform.position = new Vector2 (hit.point.x - deltaPos.x, hit.point.y - deltaPos.y);
            }
        }
    }

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

Я нашел эту статью , затем я изменил пустоту с Update() на FixedUpdate(), но результат тот же.

1 Ответ

2 голосов
/ 03 июня 2019

Попробуйте поместить свой физический код в функцию FixedUpdate(), которая построена для расчета физики. тогда, если он отстает, вы можете изменить Fixed Timestep в настройках физики.

Фиксированный временной шаг: Независимый от частоты кадров интервал, который определяет, когда выполняются физические вычисления и события FixedUpdate (). https://docs.unity3d.com/Manual/class-TimeManager.html

EDIT

этот код:

if (Physics.Raycast (ray, out hit, Mathf.Infinity))

проверяет, попал ли лучевой поток в что-то, поэтому, когда указатель выходит из сферы, больше нечего ударить, поэтому условие if возвращает false, и вы не можете его переместить, чтобы решить проблему, добавьте большой квад или плоскость как прислушайтесь к своей камере и убедитесь, что она идеально заполняет обзор камеры, и что она скрывается за всеми остальными элементами сцены.

Вы также можете сделать сценарий, который установит этот план для вас.

РЕДАКТИРОВАТЬ 2

В качестве другого подхода к решению проблемы вы можете использовать flags .

Добавьте это к своей камере или отредактируйте в соответствии со своими потребностями.

    public class DragObjects : MonoBehaviour
    {
        Camera thisCamera;
        private Transform DraggingObject;
        bool DraggingFlag = false;
        RaycastHit raycast;
        Ray ray;
        Vector3 deltaPosition;

        void Start()
        {
            thisCamera = GetComponent<Camera>();
        }
        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                ray = thisCamera.ScreenPointToRay(Input.mousePosition);
                if (Physics.Raycast(ray, out raycast, Mathf.Infinity))
                {
                    DraggingObject = raycast.collider.transform;
                    DraggingFlag = true;
                    deltaPosition = thisCamera.ScreenToWorldPoint (Input.mousePosition) - DraggingObject.position;
                }
            }
            else if (Input.GetMouseButton(0))
            {
                if (DraggingFlag)
                {
                    DraggingObject.position = new Vector3 (thisCamera.ScreenToWorldPoint (Input.mousePosition).x - deltaPosition.x, thisCamera.ScreenToWorldPoint (Input.mousePosition).y - deltaPosition.y, DraggingObject.position.z);
                }
            }
            else if (Input.GetMouseButtonUp(0))
            {
                DraggingFlag = false;
            }
        }
    }

Не забудьте обналичить ваш Camera.main в переменной в начале, потому что он не работает и делает это в фоновом режиме: GameObject.FindGameObjectsWithTag("MainCamera").GetComponent<Camera>();

...