0
votes

When dragging an object slowly with a raycast the object moves with a bit of lag.

When dragging the object fast the mouse pointer gets out of the field of layer raycasting so the object is no more moving.

The main project is dragging a cube on a plane.

But in order to make the project more simpler, I opened a new 2D project and made a circle and assigned to it the following script, and attached to it a sphere collider (the main target is in 3D space).

// 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);
            }
        }
    }

I expected to drag the sphere regularly, but what happens is that the pointer goes outside the sphere collider when moving fast, therefore the circle stops moving.

I found this article, then I changed the void from Update() to FixedUpdate() but same result.

1
Have you tried using IDragHandler and IBeginDragHandler? Does the give you the same result?Jack Mariani
No I am trying to keep my code simple as much as I could understand it easily.Youssof H.

1 Answers

2
votes

Try putting your physics code in FixedUpdate() function which is built for physics calculation. then if it's laggy, you can changeFixed Timestep in physics settings.

Fixed Timestep: A framerate-independent interval that dictates when physics calculations and FixedUpdate() events are performed. https://docs.unity3d.com/Manual/class-TimeManager.html

EDIT

this code:

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

checks if the raycast has hit something, therefore when the pointer goes out of the sphere there is nothing else to hit, so the if condition returns false and you cannot move it, to solve the problem add a big quad or plane as child to your camera and make sure it fills the camera view perfectly, and it's behind all your other scene elements.

you also can make a script that sets this plane for you.

EDIT 2

As another approach to solve the issue, you can use flags.

Add this to your camera, or edit it to your needs.

    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;
            }
        }
    }

Remember to cash your Camera.main in a variable at the start, because it is not performant and does this in the background: GameObject.FindGameObjectsWithTag("MainCamera").GetComponent<Camera>();