I'd make this more generic.
Set up a structure you can populate in the Inspector to specify a direction you're allowed to drag the object, and a minimum and maximum signed distance along this direction that it's allowed to travel from its starting point.
Expose an array of these limits, and tweak them in Start
to ensure their direction vectors are all unit length. (You could also use gizmos to visualize the limits in the scene view, or handles to edit them directly)
[System.Serializable]
public struct SlidingLimit {
public Vector2 direction;
public float min;
public float max;
}
[SerializeField]
SlidingLimit[] limits;
Vector2 startPosition;
void Start() {
startPosition = transform.position;
for(int i = 0; i < limits.Length; i++) {
var limit = limits[i];
limit.direction = limit.direction.normalized;
limit[i] = limit;
}
}
Later, inside your drag function, you can call Snap
to snap to the closest sliding limit:
Vector2 Snap(targetPosition) {
if(limits.Length == 0)
return targetPosition;
Vector2 offset = targetPosition - startPosition;
float closestRange = float.PositiveInfinity;
int closestLimit = -1;
SlidingLimit limit;
// Find which line we're closest to,
// by measuring our perpendicular distance.
for(int i = 0; i < limits.Length; i++) {
limit = limits[i];
float range = offset.x * limit.direction.y - offset.y * limit.direction.x;
if(range < closestRange) {
closestRange = range;
closestLimit = i;
}
}
// Snap the returned point to this line,
// between its min and max.
limit = limits[closestLimit];
float travel = Vector2.Dot(limit.direction, offset);
travel = Mathf.Clamp(travel, limit.min, limit.max);
return startPosition + travel * direction;
}
This will let you handle free draggables (no limits in the array), or draggables constrained to one, two, three, or any number of lines, at any angle, with custom travel limits on each, just by configuring your limits
array accordingly.