Search code examples
visual-studiounity-game-enginerotation2deuler-angles

Unity mathf.clamp in multiple angle ranges


I wanted to restrict the area of the arrow movement between -140 and -40 degrees as indicated in the drawing but as the distribution of the degrees in the angular area is strange if I limit it between -140 and -40 as a minimum and maximum respectively, it only lets me move the arrow in the red area and not in the desired one, I mean that I want to move the arrow only in the not red area, if someone can help me starting from this code without changing it much, I would be very grateful, thank you.

Edit: Added provisional code based on conditionals.

explanatory diagram

    Vector3 difference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
    difference.Normalize();
    float rotationZ = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
    //rotationZ = Mathf.Clamp(rotationZ, -140, 180);
    if (rotationZ <= -90 && rotationZ > -140) { rotationZ = -140; }
    if (rotationZ > -90 && rotationZ < -40) { rotationZ = -40; }
    transform.rotation = Quaternion.Euler(0f, 0f, rotationZ);
    
    Debug.Log(rotationZ);
    if (rotationZ < -90 || rotationZ > 90)
        {

        if (rotationZ <= -90 && rotationZ > -140) { rotationZ = -140; }
        if (rotationZ > -90 && rotationZ < -40) { rotationZ = -40; }
        if (myPlayer.transform.eulerAngles.y == 0)
            {

                transform.localRotation = Quaternion.Euler(180, 0, -rotationZ);


            }
            else if (myPlayer.transform.eulerAngles.y == 180)
            {
                transform.localRotation = Quaternion.Euler(180, 180, -rotationZ);
            }


        }
    }
}

Solution

  • private readonly float deadZone = Mathf.Sin(-40 * Mathf.Deg2Rad);
    private Vector3 rightDeadZoneEnd = new Vector3(Mathf.Cos(-40 * Mathf.Deg2Rad), Mathf.Sin(-40 * Mathf.Deg2Rad), 0);
    private Vector3 leftDeadZoneEnd = new Vector3(Mathf.Cos(-140 * Mathf.Deg2Rad), Mathf.Sin(-140 * Mathf.Deg2Rad), 0);
    
    private void Update()
    {
        Vector2 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
        direction.Normalize();
            
        if (direction.y < deadZone)
        {
            if (direction.x >= 0)
            {
                direction = rightDeadZoneEnd;
            }
            else
            {
                direction = leftDeadZoneEnd;
            }
        }
    
        if (direction.x < 0)
        {
            transform.localScale = new Vector3(1, -1, 1);
        }
        else
        {
            transform.localScale = Vector3.one;
        }
    
        direction = Quaternion.Euler(0, 0, 90) * direction;
    
        transform.localRotation = Quaternion.LookRotation(Vector3.forward, direction);
    }