Camera movement influences my mouse drag system. How do I fix that?

I have a

  • player based click and drag moving system
  • camera which follows the player

But if my Camera is moving and I hold the mouse button which I use to move the player with the click and drag system it thinks I am dragging the cursor the opposite than that the camera is moving.

this is the whole script:

using UnityEngine;
using UnityEngine.EventSystems;

public class DragAndShoot : MonoBehaviour
{
    MusicManager musicmanager;
    private void Awake()
    {
        musicmanager = GameObject.FindGameObjectWithTag("SFX").GetComponent<MusicManager>();
    }
    [Header("Movement")]
    public float maxPower;
    float shootPower;
    public float gravity = 1;

    public bool IsColliding;


    void OnCollisionEnter2D(Collision2D col)
    {
        
        if (col.gameObject.tag == "ground")
        {
            IsColliding = true;
            
        }
    }

    void OnCollisionExit2D(Collision2D col)
    {
        IsColliding = false;
    }


    public bool shootWhileMoving = false;
    public bool forwardDraging = true;
    public bool showLineOnScreen = false;

    Transform direction;
    Rigidbody2D rb;
    LineRenderer line;
    LineRenderer screenLine;

    // Vectors // 
    Vector2 startPosition;
    Vector2 targetPosition;
    Vector2 startMousePos;
    Vector2 currentMousePos;

    bool canShoot = true;



    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        rb.gravityScale = gravity;
        line = GetComponent<LineRenderer>();
        direction = transform.GetChild(0);
        screenLine = direction.GetComponent<LineRenderer>();
    }

    void Update()
    {
        

        if (Input.GetMouseButtonDown(0))
        {
             if (EventSystem.current.currentSelectedGameObject) return;  //ENABLE THIS IF YOU DONT WANT TO IGNORE UI
            MouseClick();
        }
        if (Input.GetMouseButton(0))
        {
             if (EventSystem.current.currentSelectedGameObject) return;  //ENABLE THIS IF YOU DONT WANT TO IGNORE UI
            MouseDrag();

            

        }

        if (Input.GetMouseButtonUp(0))
        {
             if (EventSystem.current.currentSelectedGameObject) return;  //ENABLE THIS IF YOU DONT WANT TO IGNORE UI
            MouseRelease();
        }


        if (shootWhileMoving)
            return;

        if (IsColliding == true)
        {
            //rb.velocity = new Vector2(0, 0); //ENABLE THIS IF YOU WANT THE BALL TO STOP IF ITS MOVING SO SLOW
            canShoot = true;
            
        }
        else
            canShoot = false;
    }

    // MOUSE INPUTS
    void MouseClick()
    {
        if (shootWhileMoving || canShoot)
        {
            Vector3 mousePosition = Input.mousePosition;
            Vector2 dir = transform.position - Camera.main.ScreenToWorldPoint(mousePosition);
            transform.right = dir * 1;
            startMousePos = Camera.main.ScreenToWorldPoint(mousePosition);
        }
    }
    void MouseDrag()
    {
        if (shootWhileMoving || canShoot)
        {
            LookAtShootDirection();
            DrawLine();

            if (showLineOnScreen)
                DrawScreenLine();

            float distance = Vector2.Distance(currentMousePos, startMousePos);
            if (distance > 1)
            {
                line.enabled = true;
                if (showLineOnScreen)
                    screenLine.enabled = true;
            }
        }
    }
    void MouseRelease()
    {
        if (shootWhileMoving /*&& !EventSystem.current.IsPointerOverGameObject()*/)
        {
            Shoot();
            screenLine.enabled = false;
            line.enabled = false;
        }
        else
        {
            if (canShoot /*&& !EventSystem.current.IsPointerOverGameObject()*/)
            {
                Shoot();
                screenLine.enabled = false;
                line.enabled = false;
            }
        }

    }


    // ACTIONS  
    void LookAtShootDirection()
    {
        Vector3 dir = startMousePos - currentMousePos;

        if (forwardDraging)
        {
            transform.right = dir * -1;
        }
        else
        {
            transform.right = dir;
        }


        float dis = Vector2.Distance(startMousePos, currentMousePos);
        dis *= 4;


        if (dis < maxPower)
        {
            direction.localPosition = new Vector2(dis / 6, 0);
            shootPower = dis;
        }
        else
        {
            shootPower = maxPower;
            direction.localPosition = new Vector2(maxPower / 6, 0);
        }

    }
    public void Shoot()
    {
        canShoot = false;
        rb.velocity = transform.right * shootPower;
        musicmanager.PlaySFX(musicmanager.shoot);

    }


    void DrawScreenLine()
    {



        screenLine.positionCount = 1;
        screenLine.SetPosition(0, startMousePos);


        screenLine.positionCount = 2;
        screenLine.SetPosition(1, currentMousePos);
    }

    void DrawLine()
    {

        startPosition = transform.position;

        line.positionCount = 1;
        line.SetPosition(0, startPosition);


        targetPosition = direction.transform.position;
        currentMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        line.positionCount = 2;
        line.SetPosition(1, targetPosition);
    }

    Vector3[] positions;


}

How do I fix that?

To fix this issue you need to store click start position in screen space and then translate it to world space when needed.

This is what was happening with the original code (camera is moving creating fantom mouse drag):
GIF 30.07.2023 21-02-50

And this is a fixed version (camera is moving but mouse drag is not affected):
GIF 30.07.2023 21-28-53

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

[RequireComponent( typeof(Rigidbody2D) , typeof(LineRenderer) )]
public class DragAndShoot : MonoBehaviour
{

    [Header("Movement")]
    public float maxPower;
    public float gravity = 1;

    public bool IsColliding;

    public bool shootWhileMoving = false;
    public bool forwardDraging = true;
    public bool showLineOnScreen = false;

    [SerializeField] float _rotationSpeed = 4;

    float forwardDraggingSign => forwardDraging ? 1f : -1f;
    float _shootPower;
    MusicManager _musicManager;
    Transform _direction;
    Rigidbody2D _rb;
    LineRenderer _line, _screenLine;
    Vector2 _mouseScreenDragStart, _mouseScreenDragEnd;
    bool _canShoot = true;
    List<Collider2D> _collidingWith = new (4);

    void Awake ()
    {
        _musicManager = GameObject
            .FindGameObjectWithTag("SFX")
            .GetComponent<MusicManager>();
    }

    void Start ()
    {
        _rb = GetComponent<Rigidbody2D>();
        _rb.gravityScale = gravity;
        _line = GetComponent<LineRenderer>();
        _direction = transform.GetChild(0);
        _screenLine = _direction.GetComponent<LineRenderer>();
    }

    void OnCollisionEnter2D ( Collision2D collision )
    {
        if( collision.collider.CompareTag( "ground" ) )
            _collidingWith.Add( collision.collider );
        
        IsColliding = _collidingWith.Count!=0;
    }

    void OnCollisionExit2D ( Collision2D collision )
    {
        if( collision.collider.CompareTag( "ground" ) )
            _collidingWith.Remove( collision.collider );

        IsColliding = _collidingWith.Count!=0;
    }

    void Update ()
    {
        var eventSystem = EventSystem.current;
        if( eventSystem==null || eventSystem.currentSelectedGameObject==null )//ENABLE THIS IF YOU DONT WANT TO IGNORE UI
        {
            Vector2 mouseScreenPosNow = Input.mousePosition;
            Vector2 mouseWorldPosNow = Camera.main.ScreenToWorldPoint( mouseScreenPosNow );

            if( Input.GetMouseButtonDown(0) )// MouseClick();
            {
                if( shootWhileMoving || _canShoot )
                {
                    //Vector2 mouseClickDirection = mouseWorldPos - (Vector2) transform.position;
                    //transform.right = mouseClickDirection * forwardDraggingSign;
                    _mouseScreenDragStart = mouseScreenPosNow;
                }
            }

            if( Input.GetMouseButton(0) )// MouseDrag();
            {
                Vector2 mouseWorldDragStart = Camera.main.ScreenToWorldPoint( _mouseScreenDragStart );
                _mouseScreenDragEnd = mouseScreenPosNow;
                
                if( shootWhileMoving || _canShoot )
                {
                    Vector3 mouseDrag = mouseWorldPosNow - mouseWorldDragStart;
                    float mouseDragDistance = mouseDrag.magnitude;

                    // void LookAtShootDirection()
                    {
                        if( mouseDragDistance>0f )
                        {
                            Vector3 newRight = mouseDrag * forwardDraggingSign;
                            transform.right = Vector3.RotateTowards(
                                transform.right ,
                                mouseDrag * forwardDraggingSign ,
                                (mouseDragDistance * mouseDragDistance) * (_rotationSpeed * Time.deltaTime) ,
                                0
                            );
                        }

                        float dis = mouseDragDistance * 4f;
                        _shootPower = Mathf.Min( dis , maxPower );
                        _direction.localPosition = new Vector2( _shootPower/6 , 0 );
                    }
                    // void DrawLine()
                    {
                        _line.positionCount = 2;
                        _line.SetPosition( 0 , transform.position );
                        _line.SetPosition( 1 , _direction.position );
                    }

                    if( showLineOnScreen )
                    {
                        // void DrawScreenLine()
                        _screenLine.positionCount = 2;
                        _screenLine.SetPosition( 0 , mouseWorldDragStart );
						_screenLine.SetPosition( 1 , mouseWorldPosNow );
                    }

                    if( mouseDragDistance>1f )
                    {
                        _line.enabled = true;
                        _screenLine.enabled = showLineOnScreen;
                    }
                }
            }

            if( Input.GetMouseButtonUp(0) )// MouseRelease();
            {
                _mouseScreenDragEnd = mouseScreenPosNow;

                if( ( shootWhileMoving || _canShoot ) /*&& !EventSystem.current.IsPointerOverGameObject()*/ )
                {
                    Shoot();
                    _screenLine.enabled = false;
                    _line.enabled = false;
                }
            }
        }

        _canShoot = !shootWhileMoving && IsColliding;
        //_rb.velocity = Vector2.zero; //ENABLE THIS IF YOU WANT THE BALL TO STOP IF ITS MOVING SO SLOW
    }

#if UNITY_EDITOR
	void OnDrawGizmos ()
	{
        if( !Application.isPlaying ) return;

        if( Input.GetMouseButton(0) )
        {
            Vector2 mouseWorldDragStart = Camera.main.ScreenToWorldPoint( _mouseScreenDragStart );
            Vector2 mouseWorldDragEnd = Camera.main.ScreenToWorldPoint( _mouseScreenDragEnd );

            Gizmos.color = Color.magenta;
            Gizmos.DrawLine( mouseWorldDragStart , mouseWorldDragEnd );

            float dragDistance = (mouseWorldDragEnd - mouseWorldDragStart).magnitude;
            UnityEditor.Handles.color = Color.Lerp( Color.white , Color.red , dragDistance*dragDistance );
            UnityEditor.Handles.Label( mouseWorldDragStart , "drag start" );
            UnityEditor.Handles.CircleHandleCap( 0 , mouseWorldDragStart , Quaternion.identity , 0.1f , EventType.Repaint );
            UnityEditor.Handles.CircleHandleCap( 0 , mouseWorldDragEnd , Quaternion.identity , 0.1f , EventType.Repaint );
            UnityEditor.Handles.CircleHandleCap( 0 , mouseWorldDragStart , Quaternion.identity , dragDistance , EventType.Repaint );
            UnityEditor.Handles.Label( mouseWorldDragEnd , $"drag distance: {dragDistance}" );
        }

        Gizmos.color = Color.yellow;
        Gizmos.DrawLine( transform.position , _direction.position );
        UnityEditor.Handles.color = Color.yellow;
        UnityEditor.Handles.RectangleHandleCap( 0 , transform.position , Quaternion.identity , 0.1f , EventType.Repaint );
        UnityEditor.Handles.RectangleHandleCap( 0 , _direction.position , Quaternion.Euler(0,0,45) , 0.1f , EventType.Repaint );
	}
#endif

    public void Shoot ()
    {
        _canShoot = false;
        _rb.velocity = transform.right * _shootPower;
        _musicManager.PlaySFX( _musicManager.shoot );
    }

}