Unity mathf.clamp в нескольких диапазонах углов

#visual-studio #unity3d #rotation #2d #euler-angles

#visual-studio #unity3d #поворот #2d #эйлер-углы

Вопрос:

Я хотел ограничить область перемещения стрелки между -140 и -40 градусами, как указано на чертеже, но поскольку распределение градусов в угловой области странно, если я ограничиваю его между -140 и -40 как минимум и максимум соответственно, это позволяет мне перемещать стрелку только в красной области ине в желаемом, я имею в виду, что я хочу переместить стрелку только в не красную область, если кто-нибудь может мне помочь, начиная с этого кода, не меняя его сильно, я был бы очень благодарен, спасибо.

Редактировать: добавлен предварительный код, основанный на условных обозначениях.

пояснительная диаграмма

     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 amp;amp; rotationZ > -140) { rotationZ = -140; }
    if (rotationZ > -90 amp;amp; rotationZ < -40) { rotationZ = -40; }
    transform.rotation = Quaternion.Euler(0f, 0f, rotationZ);
    
    Debug.Log(rotationZ);
    if (rotationZ < -90 || rotationZ > 90)
        {

        if (rotationZ <= -90 amp;amp; rotationZ > -140) { rotationZ = -140; }
        if (rotationZ > -90 amp;amp; 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);
            }


        }
    }
}
  

Комментарии:

1. Это 3D-игра, и функция похожа на то, чтобы оглядываться в Rust, нажимая Alt, чтобы символ не выглядел на 180 градусов позади?

2. Мне не нравится этот код, но, по крайней мере, вы можете использовать if(rotationZ <= -90 amp;amp; rotationZ > -140) {rotationZ = -140;} if(rotationZ > -90 amp;amp; rotationZ < -40) {rotationZ = -40;}

3. @Whitebrim Что бы вы сделали вместо этого? Я заинтересован в изучении более эффективного способа. Я прилагаю полный код, поскольку есть также часть, в которой я изменяю поворот изображения, чтобы оно создавало зеркальную версию.

4. измените -140 на 220

5. @Antoine да, но это уравнение степени окружности, просто простой трюк, Unity преобразует его, добавляя или вычитая 360 градусов, это означает, что 220 равно -140, это преобразование заставит вашу стрелку переместиться с -140 на -40 в области, не обозначенной. просто попробуйте rotationZ = Mathf. Зажим (вращение Z, -40, 220);

Ответ №1:

 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);
}
  

Ответ №2:

     void FixedUpdate()
    {
        
        Vector3 difference = Camera.main.ScreenToWorldPoint(Input.mousePosition) 
        - transform.position;
        difference.Normalize();
        float rotationZ = Mathf.Atan2(difference.y, difference.x) * 
        Mathf.Rad2Deg;

        if (rotationZ <= -90 amp;amp; rotationZ > -140) { rotationZ = -140; }
        else if (rotationZ > -90 amp;amp; rotationZ < -40) { rotationZ = -40; }

        transform.rotation = Quaternion.Euler(0f, 0f, rotationZ);

        if (rotationZ < -90 || rotationZ > 90)
        {
            if (rotationZ <= -90 amp;amp; rotationZ > -140) { rotationZ = -140; }
            else if (rotationZ > -90 amp;amp; 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);
            }
        }
    }
}