# joystick boundary is rectangle not cycle

HI, folks! Ive got problem with distance measurement between two screen positions (Vector2) - joysticks boundary is rectangle like, but it should be like cycle (i thought using distance variable as radius and it would provide cycle like boundary).

PS. this script is based on Penelope tutorial Joystick script

``````                var clampedPos: Vector2;
clampedPos.x = Mathf.Clamp(touchPos.x,guiBoundary.min.x,guiBoundary.max.x);
clampedPos.y = Mathf.Clamp(touchPos.y,guiBoundary.min.y,guiBoundary.max.y);

var distance: float=Vector2.Distance(defPos,clampedPos);

if(distance<moveDistance)
{

gui.pixelInset.x=clampedPos.x;
gui.pixelInset.y=clampedPos.y;
}
``````

What you need is Vector2.ClampMagnitude. If you clamp the two axis seperated it will always be a rectangle

``````touchPos = Vector2.ClampMagnitude(touchPos,moveDistance);
``````

Ah, given you’re picture the problem is clearer - your gui boundary is smaller than you’re moveDistance. You need to clip an area inside the rectangle - so the guiboundary needs to be at least moveDistance on its shortest side. Bunny83’s answer is the way to code it, once you’ve checked that the touch is inside the rectangle (otherwise it will move the joystick for a touch anywhere, presumably not what you want).

//you need two round texture one for boundary are which is bigger then 2nd texture which will //be touch and drag for controlling

public class JoyStick : MonoBehaviour {

``````public Texture areaTexture;
public Texture touchTexture;
public Vector2 joystickPosition = new Vector2( 135f,135f);
public Vector2 speed = new Vector2(2,100);
public float touchSize = 30;
public float touchSizeCoef=0;
protected Vector2 joystickAxis;
protected Vector2 joystickValue;
public Vector2 joyTouch;
private Vector2 _joystickCenter;
[SerializeField]
private Vector2 _smoothing = new Vector2(20f,20f);
public Vector2 Smoothing
{
get {
return this._smoothing;
}
set {
_smoothing = value;
if (_smoothing.x<0.1f){
_smoothing.x=0.1f;
}
if (_smoothing.y<0.1){
_smoothing.y=0.1f;
}
}
}
private int _joystickIndex=-1;
private bool _enaReset;
private bool _enaZoom;

void Start ()
{
_joystickCenter = joystickPosition;
_enaReset=false;
}

void Update ()
{
if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.Android)
{
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
{
if (_joystickIndex==touch.fingerId){
_joystickIndex=-1;
_enaReset=true;
}
}

if(_joystickIndex==touch.fingerId)
{
OnTouchDown(touch.position);
}
if (touch.phase == TouchPhase.Began)
{
if (((Vector2)touch.position - _joystickCenter).sqrMagnitude < Mathf.Pow((zoneRadius+touchSizeCoef/2),2))
{
_joystickIndex = touch.fingerId;
}
}
}

UpdateJoystick();
if(_enaReset)
{
ResetJoystick();
}
}
else
{
if (Input.GetButtonUp ("Fire1"))
{
_joystickIndex=-1;
_enaReset=true;
}
if(_joystickIndex==1)
{
OnTouchDown(Input.mousePosition);
}
if (Input.GetButtonDown ("Fire1") )
{
if (((Vector2)Input.mousePosition - _joystickCenter).sqrMagnitude <Mathf.Pow( (zoneRadius+touchSizeCoef/2),2))
{
_joystickIndex = 1;

}

}
if(_enaReset)
{
ResetJoystick();
}

UpdateJoystick();

}

}

private void UpdateJoystick()
{
{

joystickAxis = Vector2.zero;
{

}
else
{
joystickAxis = new Vector2( joyTouch.x /(zoneRadius-touchSizeCoef),joystickAxis.y);

}
{
}
else{
}

}
else{
joystickAxis = new Vector2(0,0);
}
Vector2 realvalue = new Vector2(  speed.x*joystickAxis.x,speed.y*joystickAxis.y);
joystickValue=realvalue;
print(realvalue);

}

void OnTouchDown(Vector2 position)
{
joyTouch  = new Vector2( position.x, position.y) - _joystickCenter;
{
joyTouch.Normalize();
}
//print(joyTouch);
}

private void ResetJoystick()
{
if (joyTouch.sqrMagnitude>0.1)
{
joyTouch = new Vector2( joyTouch.x - joyTouch.x*_smoothing.x*Time.deltaTime, joyTouch.y - joyTouch.y*_smoothing.y*Time.deltaTime);
}
else{
joyTouch = Vector2.zero;
_enaReset=false;
}
}
void OnGUI()
{