UI Thumb Knob That Only Moves Inside A Circular Route

Hi,

I want to move a UI thumb knob into the circular UI route with pointer input.

Like that;

The red thumb knob can move only inside the blue circular line, if player drag this thumb knob outside the blue perimeter it stops moving.

I tried this so far, but no luck. Can you help me with that? Thanks.

 public void OnDrag(PointerEventData eventData)
    {
        Vector2 clickPos;

        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
            this.GetComponent<RectTransform>(),
            eventData.position,
            eventData.pressEventCamera,
            out clickPos
            ))
        {
            //if (isPointerInsideThumbKnob == true)
            //{
                //clickPos.x = clickPos.x / innerCircleController.GetComponent<RectTransform>().sizeDelta.x;
                //clickPos.y = clickPos.y / innerCircleController.GetComponent<RectTransform>().sizeDelta.y;

                //Vector3 inputDirection = new Vector3(clickPos.x, 0, clickPos.y);
                //inputDirection = (inputDirection.magnitude > 1) ? inputDirection.normalized : inputDirection;
                //inputDirection = (inputDirection.magnitude < 0.9f) ? inputDirection.normalized : inputDirection;

                //this.GetComponent<RectTransform>().anchoredPosition = Vector2.Lerp(this.GetComponent<RectTransform>().anchoredPosition, new Vector2(inputDirection.x, inputDirection.z) * 45, Time.deltaTime * 240);
                clickPos.x = clickPos.x / innerCircleController.GetComponent<RectTransform>().sizeDelta.x;
                clickPos.y = clickPos.y / innerCircleController.GetComponent<RectTransform>().sizeDelta.y;

            float x = clickPos.x * 2 - 1;
            float y = clickPos.y * 2 - 1;
                inputDirection = new Vector3(x, 0, y);
            print(inputDirection.magnitude);
            if(inputDirection.magnitude > 1.5 && inputDirection.magnitude < 2.5f)
            {
                this.GetComponent<RectTransform>().anchoredPosition = new Vector2(inputDirection.x * (innerCircleController.GetComponent<RectTransform>().sizeDelta.x / 2), inputDirection.z * (innerCircleController.GetComponent<RectTransform>().sizeDelta.y / 2));
            }
               // inputDirection = (inputDirection.magnitude > 1 || inputDirection.magnitude < 0.88f) ? inputDirection.normalized : inputDirection;

            
            //}
            //clickPos.x = (clickPos.x / innerCircleController.GetComponent<RectTransform>().sizeDelta.x);
            //clickPos.y = (clickPos.y / innerCircleController.GetComponent<RectTransform>().sizeDelta.y);

            //float x = (this.GetComponent<RectTransform>().pivot.x == 1) ? clickPos.x * 2 + 1 : clickPos.x * 2 - 1;
            //float y = (this.innerCircleController.GetComponent<RectTransform>().pivot.y == 1) ? clickPos.y * 2 + 1 : clickPos.y * 2 - 1;

            //inputDirection = new Vector3(x, 0, y);
            //float dist = Vector2.Distance(innerCircleController.GetComponent<RectTransform>().rect.center, this.GetComponent<RectTransform>().anchoredPosition);
            //if (isPointerInsideThumbKnob == true)
            //{
            //    //this.GetComponent<RectTransform>().anchoredPosition = (this.GetComponent<RectTransform>().anchoredPosition - innerCircleController.GetComponent<RectTransform>().anchoredPosition).normalized * 45 + new Vector2(inputDirection.x * 5, inputDirection.z * 5);
            //    inputDirection = new Vector3(clickPos.x, 0, clickPos.y);
            //    float dist = Vector2.Distance(innerCircleController.GetComponent<RectTransform>().rect.center, this.GetComponent<RectTransform>().anchoredPosition);

            //    if (dist <= 45 && dist >= 37)
            //    {
            //        this.GetComponent<RectTransform>().anchoredPosition = Vector2.Lerp(this.GetComponent<RectTransform>().anchoredPosition, new Vector2(inputDirection.x * 5, inputDirection.z * 5), Time.deltaTime * 7);
            //        //this.GetComponent<RectTransform>().anchoredPosition = new Vector2(inputDirection.x * (innerCircleController.GetComponent<RectTransform>().sizeDelta.x / 2), inputDirection.z * (innerCircleController.GetComponent<RectTransform>().sizeDelta.y / 2));
            //    }
            //    else if (dist > 45)
            //    {
            //        float distDifference = dist - 45;
            //        print(distDifference);
            //        this.GetComponent<RectTransform>().anchoredPosition += new Vector2(distDifference + .1f, distDifference + .1f);
            //    }
            //    else if (dist < 37)
            //    {
            //        float distDifference = 37 - dist;
            //        print(distDifference);
            //        this.GetComponent<RectTransform>().anchoredPosition += new Vector2(distDifference + .1f, distDifference + .1f);
            //    }
            //}

        }

    }

I finally found the solution;

   private bool isPointerInsideThumbKnob = false;
    public Image innerCircleController;

    private RectTransform innerCircleRectTransform;
    private RectTransform thumbKnobRectTransform;
    private Vector3 inputDirection;

    private Vector2 clickPos = Vector2.zero;

    private Vector2 thumbKnobLastPosition;
    // Use this for initialization
    void Start () {
        inputDirection = Vector3.zero;

        innerCircleRectTransform = innerCircleController.GetComponent<RectTransform>();
        thumbKnobRectTransform = this.GetComponent<RectTransform>();
    }
    public void OnDrag(PointerEventData eventData)
    {

        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
            innerCircleController.GetComponent<RectTransform>(),
            eventData.position,
            eventData.pressEventCamera,
            out clickPos
            ))
        {

            clickPos.x = clickPos.x / innerCircleRectTransform.sizeDelta.x;
            clickPos.y = clickPos.y / innerCircleRectTransform.sizeDelta.y;

            inputDirection = new Vector3(clickPos.x*2+1, 0, clickPos.y*2+1);
            inputDirection = (inputDirection.magnitude > 1.3 || inputDirection.magnitude < 1f) ? inputDirection.normalized : inputDirection;

            thumbKnobRectTransform.anchoredPosition = new Vector2(inputDirection.x * (innerCircleRectTransform.sizeDelta.x / 3), inputDirection.z * (innerCircleRectTransform.sizeDelta.y / 3));
        }
    }

With a circle like that, I would imagine that you can take the position from your click to get an angle, and then use the radius of the blue circle to set position of the knob from that?

1 Like