How to limit mousePosition based on distance (2D)

Let’s say I have a slingshot system that requires the player to pull to throw but I only manage to limit the player pull back distance by position on screen by using Mathf.Clamp which it will lock the mousePosition within the limited screen position.

Vector2 mosPos = Input.mousePosition;
Vector3 vel = GetForceFrom(_skills.transform.position, Camera.main.ScreenToWorldPoint(mosPos));
Vector3 newLimit = new Vector3 (Mathf.Clamp (vel.x, -10, 10),Mathf.Clamp (vel.y, -10, 0));

How do I write a code that does the limitation on the mousePosition based on the distance?
Which do I even use and how do I write it?

Vector3.Distance
Vector3.magnitude
Vector3.sqrMagnitude

I want the limitation to be half circle at the bottom and only able to pull to a certain distance.
57106-capture.png
PS: Sorry if the word I used here are bad or confusing.

UPDATE: to the above code, here’s what its look like in full for the Update()
since it’s void I had to modified the code to test around but it still doesn’t limit the pull back range. Any thoughts?

        void Update ()
        	{
        		Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        		RaycastHit hit;
        
        		if(isSkillsThrown)
        			return;
                if (isPlayerTurn)
                {
                    if (Input.GetMouseButtonDown(0))
                    {
                        if (Physics.Raycast(ray, out hit) && hit.collider.CompareTag("Player"))
                        {
                            isPressed = true;
                            if (!_skills)
                                createSkills();
                            isClickOnObj = true;
                        }
                        else
                        {
                            isClickOnObj = false;
                        }
                    }
                    else if (Input.GetMouseButtonUp(0))
                    {
                        isPressed = false;
                        GameObject[] trajDes;
                        trajDes = GameObject.FindGameObjectsWithTag("Trajectory");
        
                        for (int i = 0; i < trajDes.Length; i++)
                        {
                            Destroy(trajDes*.gameObject);*

}
if (isClickOnObj == true)
{
if (!isSkillsThrown)
{
throwSkills();
}
}

//isPressed = true;
//[Remove comment below for unlimited shots]
ManualStart();
}
}

  •  // when mouse button is pressed, cannon is rotated as per mouse movement and projectile trajectory path is displayed.*
    
  •  if(isPressed)*
    
  •  {*
    

//I would like to add the limit here
Vector2 mosPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector3 vel = GetForceFrom(_skills.transform.position, mosPos);

  •  	Vector3 newLimit = new Vector3 (Mathf.Clamp (vel.x, -10, 10),Mathf.Clamp (vel.y, -10, 0));*
    
  •  	Debug.Log("VEL: "+vel+" newLimit: "+newLimit);*
    

_ Vector3 newVel = newLimit * -1;_

  •  	setTrajectoryPoints(transform.position, newVel/_skills.GetComponent<Rigidbody>().mass);*
    
  •  }*
    
  • }*

private Vector2 GetForceFrom(Vector3 fromPos, Vector3 toPos)

  • {*
    _ return (new Vector2(toPos.x, toPos.y) - new Vector2(fromPos.x, fromPos.y))* power;_
  • }*
    I had all the formula correct already but all I need to do left is to place the limit in that specific location which I only know by using Mathf.Clamp and use screen position.

All you need to use is Mathf.Min instead of Mathf.Max. Keep the second value to 0f. There’s also Vector2.ClampMagnitude which directly does the clamping to a circle:

Vector2 mosPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 pointA = _skills.transform.position;
Vector2 diff = mosPos - pointA;
diff.y = Mathf.Min(0f, diff.y);

float radius = 10.0f;

diff = Vector2.ClampMagnitude(diff, radius);

Vector2 pointB = pointA + diff;

Mathf.Max just returns the greater number while Mathf.Min returns the smaller number. They are implemented literally just like that:

public static float Max(float a, float b)
{
    if (a > b)
        return a;
    return b;
}

public static float Min(float a, float b)
{
    if (a < b)
        return a;
    return b;
}

When using screen coordinates as well as x-y-world coordinates the y value will grow when you go upwards. So you want to limit your y value of your direction to be 0 or less. So Mathf.Min with your y value will just return the y value when it’s smaller than 0. If it’s greater than 0 it’s limited to 0.

A one side boundary could also simply be done like this:

if (diff.y > 0f)
    diff.y = 0f;

This would be a tiny bit faster since you save a method call. However such differences are irrelevant.

Try something like this (Untested):

        public Vector3 startingPos; //the starting position of the "slingshot" (you may be able to replace this with transform.position)
		public float maxPullDistance = 4f; //the max distance you can pull the "slingshot" from the startingPos
				
		Vector3 GetMousePos()
		{
			Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); //get the current mousPos
			if(Vector3.Distance(startingPos, mousePos) <= maxPullDistance) 
			{ 
				return mousePos;
			}
			else
			{
				//we need to make sure mousePos is within maxPullDistance
				Vector3 dir = (mousePos - startingPos).normalized;
				return startingPos + (dir * maxPullDistance);
			}
		}