Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by NinjaSquirrel · Apr 28, 2011 at 10:16 PM · euleranglesmouselookangles

Wrapping Euler Angles To Achieve Mouse Look

I am attempting to limit the player's view at the x euler angle of -80 and 80 (not final values), to prevent the player looking upside down. I do this by "wrapping" the values so I can work with angles in the range of -90 to 90 instead of 90 to 0 and 270 to 360 which aren't good for clamping the values, which I also do (360 degrees will now be -90 and so on). That clamp part works just fine.

Please consider the following code:

var wrappedX : float;

Inside update function:

transform.localEulerAngles = Vector3(Mathf.Clamp (wrappedX, -80, 80), 0, 0);

if (transform.localEulerAngles.x >= 270) { wrappedX = transform.localEulerAngles.x - 360; } else { wrappedX = transform.localEulerAngles.x; }

print(Vector3(Mathf.Clamp (wrappedX, -80, 80), 0, 0));

It appears to be working fine except for the part where I actually assign the x euler angle as the new clamped value In this part of the code that you also read above:

transform.localEulerAngles = Vector3(Mathf.Clamp (wrappedX, -80, 80), 0, 0);

For some reason the player's x euler angle is forced to 0, therefor the player can only look side to side (handled in other code not shown), and not up or down at all. the player's view is stuck at 0 degrees.

So what specifically am I doing wrong here? I am very new to angles and stuff so exact code on what will fix it is perfered. Can anyone help me out here? Thanks.

EDIT: After more testing I have concluded that the problem is not that code, but the way it combines with this code:

transform.Rotate (lookSpeed * -Input.GetAxis ("Mouse Y"),0, 0)

This is causing the player's view to not be able to move.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

6 Replies

· Add your reply
  • Sort: 
avatar image
5
Best Answer

Answer by Joshua · Apr 29, 2011 at 12:36 AM

What you're doing wrong is that you're using Eulerangles in a way you should not. As you can see here, you should directly set them to an absolute value and not increment them.

"Only use this variable to read and set the angles to absolute values. Don't increment them, as it will fail when the angle exceeds 360 degrees. Use Transform.Rotate instead."

I guess you could work around this by when ever it exceeds 360 or get's lower then 0, use modulo.

var x = 740;
var moduloX = 740 % 360 //which is 20;

But I advice just using transform.Rotate.


edit: do it like this:

var minimumX : float = -360; var maximumX : float = 360;

var rotationX : float = 0;

private var originalRotation : Quaternion;

function Update () { rotationX += Input.GetAxis("Mouse X") sensitivityX; rotationX = ClampAngle (rotationX, minimumX, maximumX); xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.up); transform.localRotation = originalRotation xQuaternion; }

and include the ClampAngle function of course (my bad, sorry):

static function ClampAngle (angle : float, min : float, max : float) : float {
    if (angle < -360.0)
        angle += 360.0;
    if (angle > 360.0)
        angle -= 360.0;
    return Mathf.Clamp (angle, min, max);
}
Comment
Add comment · Show 13 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image NinjaSquirrel · Apr 29, 2011 at 09:21 PM 0
Share

Can you elaborate on how I would use transform.Rotate in this situation specifically?

avatar image Joshua · Apr 30, 2011 at 12:38 AM 0
Share

I'd advice just checking out the mouseLook script that comes standard with Unity. It does exactly this for both x and y with a variable clamp. Just distill from there. :)

avatar image Joshua · May 01, 2011 at 06:26 AM 0
Share

I edited the answer.

avatar image NinjaSquirrel · May 01, 2011 at 04:34 PM 0
Share

$$anonymous$$ identifier: 'ClampAngle'.

avatar image Bunny83 · May 07, 2011 at 02:26 AM 1
Share

It doesn't "increment" in script but you can change the value in the inspector as you like and if you assign values smaller than 0 or greater than 360 to eulerAngles the assignment will fail (and as far as i can remember the quaternion turns to identity [0,0,0]). Quaternions have been invented to circumvent such problems by adding another dimension. This script should work fine. Btw, original rotation is only needed if you have a different startrotation. If you want assign an absolute rotation just assign the result of AngleAxis to localRotation.

Show more comments
avatar image
4

Answer by superpig · May 03, 2011 at 09:45 AM

That's a rather odd sequence of operations you've got going on there. Why not get the 'wrappedX' variable to have the right value first, and then use it to set up localEulerAngles?

wrappedX += Input.GetAxis("Vertical"); while(wrappedX > 180) wrappedX -= 360; while(wrappedX < -180) wrappedX += 360; wrappedX = Mathf.Clamp(wrappedX, -80, 80);

transform.localEulerAngles = new Vector3(wrappedX, 0, 0);

That way you'll be more easily able to watch the value of wrappedX in the inspector.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Quazistax · May 07, 2011 at 01:56 AM 0
Share

Oh, now I see your answer... yes, that's his problem :)

avatar image superpig ♦♦ · May 07, 2011 at 02:38 PM 0
Share

@Joshua - please don't edit my answers without at least leaving a note as to what you've changed.

avatar image Joshua · May 07, 2011 at 02:59 PM 0
Share

Oh, I'm sorry - I just changed the last sentence's grammar because it seemed wrong to me xD and I gave you my upvote to by the way ;). Also - you can check what I did for yourself if you click edit and check the revision history.

avatar image superpig ♦♦ · May 07, 2011 at 04:48 PM 0
Share

Ah, I see. Thanks for the pointer.

avatar image
1

Answer by Edy · May 20, 2011 at 11:19 PM

Here is an universal ClampAngle function that accepts euler angles works properly in any situation and any input values:

 function ClampAngle (a : float, min : float, max : float) : float 
 {
 while (max < min) max += 360.0;
 while (a > max) a -= 360.0;
 while (a < min) a += 360.0;
 
 if (a > max)
     {
     if (a - (max + min) * 0.5 < 180.0)
         return max;
     else
         return min;
     }
 else
     return a;
 }

It's not mine, I found it somewhere (maybe at UnifyCommunity, don't remember). I had problems with all other angle clamp methods, especially when smoothing the camera movement. But the above function is the only one that worked properly.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Eric5h5 · Apr 28, 2011 at 11:08 PM

The default MouseLook script does this, or at least the original version did. This is a JS translation of it.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image NinjaSquirrel · Apr 28, 2011 at 11:14 PM 0
Share

I have looked at that script and I still don't see what I am doing wrong here.

avatar image
0

Answer by Quazistax · May 07, 2011 at 01:47 AM

:D

let's see....

You declare variable, and it's initial value is 0.

var wrappedX : float;

Then you assign rotation to transform, creating Vector3(0,0,0).

transform.localEulerAngles = Vector3(Mathf.Clamp (wrappedX, -80, 80), 0, 0);

Then you read that rotation (0,0,0) and compute value to assign to wrappedX, value that will be always 0.

if (transform.localEulerAngles.x >= 270) {
         wrappedX  = transform.localEulerAngles.x - 360;
    }
    else {
        wrappedX = transform.localEulerAngles.x;
    }

And in new Update call, you do it all over again, wrappedX is still 0, and you reset localRotationAngles to (0,0,0).

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Joshua · May 07, 2011 at 01:57 AM 0
Share

Ehm, the variable wrappedX get's assigned a value in the inspector. Do you realize it's placed outside the update function? o.O

avatar image Quazistax · May 07, 2011 at 02:43 AM 0
Share

Hm, then he should supply more information, where, how and what he assigns to it... seems like problem is somewhere out there :) Because, his results are like wrappedX is never set, or set to 0. Of course, I don't exclude some other possibility, but this one should be checked first.

avatar image NinjaSquirrel · May 07, 2011 at 09:49 PM 0
Share

wrappedX is set to 0 at default.

avatar image NinjaSquirrel · May 07, 2011 at 10:04 PM 0
Share

wrappedX gets assigned properly when the game runs.

avatar image NinjaSquirrel · May 07, 2011 at 10:50 PM 0
Share

$$anonymous$$ore information was added to the original post.

  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

2 People are following this question.

avatar image avatar image

Related Questions

Rotation losing precision 0 Answers

Rotation around z-axis always local space and not world? Vector-axis angle projection calcuations. 0 Answers

Aligning/mapping angles of Input.GetAxis(with .localEulerAngles 0 Answers

Problem when checking a Quaternion Eulerangle axis 1 Answer

localEulerAngles.x changes when the angle is close to -90 in the inspector 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges