Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

319
Visualizações
Unity - 2D Aim at Mouse, while restricting min/max rotation and factoring in parent rotation

So, I have a ship with a "Hardpoint" attached to it that weapons can be placed on to. Once placed, they aim at the mouse position and have a restricted rotational range: See here

The rotational range is based off minAngle and maxAngle, and are calculated by the eulerAngles.z of the parent hardpoint slot, plus/minus the angle modifier (in this case, 20). I had to do some weird rotational voodoo (see OneEightyToThreeSixty() in the code snippet) to get the mouse look angle to match the same format as the minAngle/maxAngle.

angle was coming in as -180 -> 180 degrees instead 0 -> 360 like the hardpoint's rotation. Wrote a method to convert it to 360 during runtime.

I've rewritten this script more times than I can count, but ultimately I'm hit with this issue.

As you can see, for 270 degrees of the 360 rotation, the aiming and restrictions work totally fine. But at the top right quarter of the rotation, it all goes haywire.

I've tried so many different implementations but they all seem to have this consistent issue. I cannot figure out what I'm missing. Here's the code:

public class HardpointSlot : MonoBehaviour
{
    public HardpointController ship;
    public GameObject hardpoint;

    public float minAngle;
    public float maxAngle;
    public float angle;
    public float offsetAngle;
    public bool switched;

    void Update()
    {
        AimAtMouse();
    }

    public void AimAtMouse()
    {
        Vector3 dir = Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position);

        angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;

        minAngle = (transform.eulerAngles.z - 20) + 90f;
        maxAngle = (transform.eulerAngles.z + 20) + 90f;

        angle = OneEightyToThreeSixty(angle);
        if (angle < minAngle)
        {
            angle = minAngle;
        }
        else if (angle > maxAngle)
        {
            angle = maxAngle;
        }

        hardpoint.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
    }

    public float OneEightyToThreeSixty(float angle)
    {
        float newAngle = 0f;

        if (angle >= 0 && angle <= 180)
        {
            return angle;
        } else
        {
            return newAngle = 360 + angle;
        }


    }
}

So quick recap:

  • Hardpoint needs to look at mouse but only if its within its aim range bounds, which is calculated by the baseAim offset (20) and the rotation of the parent hardpoint slot.
  • Works for 270 degrees of rotation but not for the last 90.

Any ideas? Am I missing something very obvious?

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

I would take another approach, making use of Vector3.SignedAngle to get the angle from the neutral direction to the mouse direction. Then, use Mathf.Clamp to clamp it between the boundaries and then Quaternion.AngleAxis to create the resulting direction. Finally, use Quaternion.LookRotation to assign the rotation to the hardpoint's transform:

public class HardpointSlot : MonoBehaviour
{
    [SerializeField] HardpointController ship;
    [SerializeField] GameObject hardpoint;

    [SerializeField] float minAngle;
    [SerializeField] float maxAngle;
    [SerializeField] float angle;

    void Update()
    {
        AimAtMouse();
    }

    public void AimAtMouse()
    {
        Vector3 dir = Camera.main.ScreenToWorldPoint(Input.mousePosition)
                - transform.position;

        // flatten z axis
        dir.z = 0;
    
        Vector3 neutralDir = transform.up;
        float angle = Vector3.SignedAngle(neutralDir, dir, Vector3.forward);
    
        minAngle = -20f;
        maxAngle = 20f;
        
        angle = Mathf.Clamp(angle, minAngle, maxAngle);
       
        // rotate neutral dir by the clamped angle
        dir = Quaternion.AngleAxis(angle, Vector3.forward) * neutralDir;
    
        // set the rotation so that local up points in dir direction 
        // and local forward in global forward
        hardpoint.transform.rotation = Quaternion.LookRotation(Vector3.forward, dir);
    }
}

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda