Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

329
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!