1
\$\begingroup\$

I'm trying to get a simple cannon to rotate to point at the mouse, but I only want it to follow the mouse for 180 degrees and then stop following the mouse, and pick up again when the player re-enters the 180-degree area. I got the cannon to follow the user's mouse but when I tried to camp it to the 180-degree area I found it worked for one side, but when I went to the other it "teleported" to the other side.

I video to explain my issue: https://i.stack.imgur.com/ZVNCn.jpg Sorry about the crude graphics, frame rate, and the software doesn't show my mouse making things more difficult, but as you can see, the clamp works fine when I move my mouse to the right, but when I move it to the left it "teleports" or instantly moves to teh right no matter where my mouse is.

Here is my code:

public int rotationOffset = -90;

    // Update is called once per frame
    void Update()
    {
        var mouse = Input.mousePosition;
        var screenPoint = Camera.main.WorldToScreenPoint(transform.localPosition);
        var offset = new Vector2(mouse.x - screenPoint.x, mouse.y - screenPoint.y);
        var angle = Mathf.Atan2(offset.y, offset.x) * Mathf.Rad2Deg;
        float finalRotation = angle + rotationOffset;

        // I have tried both the normal Mathf.Clamp and the if statments below and I get the exact same result.
        //finalRotation = Mathf.Clamp(180, 0, finalRotation);

        if (finalRotation >= 89f)
        {
            finalRotation = 89f;
            Debug.Log("Left");
        }

        else if(finalRotation <= -89f)
        {
            finalRotation = -89f;
            Debug.Log("Right");
        }


        transform.rotation = Quaternion.Euler(0, 0, finalRotation);

    }

I don't know if this might be a bug in Unity, But I've spent days trying to fix it, I'm tired, I'm stressed, I don't know how to fix it.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

As you've found, clamping an angle can be surprisingly tricky. To illustrate your particular problem, here's a couple of crappy diagrams:

atan2 output

This is the output from atan2 for some various vectors. Note that it wraps at 180/-180. (The Unity docs do not specify this, but it's how the function normally operates regardless of the framework.)

Then, here is the output after applying your -90 degree offset (in other words, the value of finalRotation):

rotation after applying -90 deg offset

You might notice something - the value of the angle never goes above 90. That means the body of the if statement which checks for finalRotation >= 89f is basically never executed.

For a quick fix, just looking at the angles in the above diagram, you should be able to do something like this:

if (finalRotation < -90)
{
  if (finalRotation > -180)
  {
    // we're on the right
  }
  else
  {
    // we're on the left
  }
}

However, I'd suggest you look into more generic angle clamping/comparison functions. As you noted, Mathf.Clamp will not do the job because it doesn't know that angles wrap around a circle. Something like the one described in this post might do the job.


As a word of encouragement, the final plea for help in your post is something I've felt all to commonly when running into problems like this. I've found it helpful to take a deep breath, step back, and view the problem analytically before losing hope. If all else fails, remember you can easily get a second opinion - just like you've done here - before you reach the point of utter frustration.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Thank you for your help solving my problem, and thank you very very much for your words of encouragement, I appreciate it. I will also take your advice into account next time I get stuck. Also, This sounds silly and I'm sorry to do this to you but can I ask you one more favor? Can you upvote my question? You've even said "If all else fails, remember you can easily get a second opinion - just like you've done here", For whatever reason, if I don't get at least 1 upvote on my questions total, Stackexchange stops me from asking new question because "I are not contributing to the community". \$\endgroup\$ Aug 2, 2019 at 2:09
  • 1
    \$\begingroup\$ Thanks for the reminder, I did not know about that restriction and habitually forget to upvote questions. \$\endgroup\$
    – Chaosed0
    Aug 2, 2019 at 18:22
  • \$\begingroup\$ Thank you so much for your help fixing my problem, providing encouragement, and allowing me to ask more questions in the future, thanks a million! \$\endgroup\$ Aug 2, 2019 at 20:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .