• 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
0
Question by Vectorizing · Jul 21, 2013 at 11:07 PM · c#degreeslocaleulerangles

How to rotate an object on the z-axis using localeulerangles?

Okay so im trying to make my character rotate left and right through the Z-Axis.

Here is the script I have written and what it does: (C#)

 public int LeanAnglePositive = 30;
 public int LeanAngleNegitive = 330;
 public int SpeedOfLean;
 
 void Update ()
 {
      if (Input.GetKey(KeyCode.Q) && transform.localEulerAngles.z < LeanAnglePositive)
      {    
            transform.Rotate(Vector3.forward * Time.deltaTime * SpeedOfLean);    //Center to Left
      }
 }

Note: Z rotation axis on this object is default at 0.

So in this block of code it is rotating from 0 to 30 degrees on the z-axis.

This block of code works fine. Except for the fact that I have to hold Q instead of just pressing it. (I have tried GetButtonDown, it only works for 1 frame)

So now I want to go from 0 degrees to -30 (or 330) degrees on the z-axis so I wrote this block of code:

 if (Input.GetKey(KeyCode.E) && transform.localEulerAngles.z > LeanAngleNegitive)    //Center to Right
 {
             transform.Rotate(-Vector3.forward * Time.deltaTime * SpeedOfLean);
 }

As you can see in order to make it go backwards I added a Negative sign in front of the vector3, it works but it only works for 1 frame because instead of going from 0 to -30, it goes to 358 degrees, therefore since that 1 frame made it 358 degress it makes the "if" statement untrue and does not keep updating, im at a loss and do not know what to do next.

To sum up:

Player needs to lean 30 degrees to the left and right from 0 degrees on the z-axis smoothly.

when I hold Q it smoothly rotates to the left and stops at 30 degrees. (so 0 to 30) but when I try pushing E from the same position (0 degrees on the z-axis) to goes to 358 degrees in the 1st frame like the object is wanting to lean left, but then stops because the if statement no longer is true. This part(transform.localEulerAngles.z > LeanAngleNegitive).

also 1 more thing, what determines if the rotation is using 330 degrees or -30 degrees? I hope that makes sense.

Any help is appreciated.

Thanks!

Comment
Add comment · Show 1
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 Benproductions1 · Jul 21, 2013 at 11:07 PM 0
Share

Do not double post questions!!!

1 Reply

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

Answer by Peter G · Jul 21, 2013 at 11:43 PM

Okay. Let me just double check that I am correctly understanding your question. You want to be able to tap a key and then it will rotate all the way to the max angle and then stop?

First let me say that it sounds like you want -30 degrees. The two angles are on the same point on the unit circle, but it's important because it affects which direction we want to rotate.

 public enum RotationDirection {
      rotatingLeft = -1 , 
      resting = 0, 
      rotatingRight = 1
 } 
 
 public float maxAngle = 30;
 //since you're rotating 30 degrees in both, we'll simplify everything and just say we can't rotate
 //more than 30 degrees in either direction
 
 public float rotationSpeed = 15;
 //It'll take 2 seconds to hit the extremes from the center.
 
 private RotationDirection currentRotationDirection = RotationDirection.resting;
 //we're going to use an enum to store our current state.
 private float internalAngleStorage = 0;
 //THIS IS HOW WE ARE GOING TO AVOID THE 330 VS. -30 ISSUE
 //By storing the angle internally, we don't need to worry about the value unity
 //reports
 
 public void Update () {
      if ( Input.GetKeyDown ( KeyCode.Q ) ) {
      //Did the user press the button.
           if ( currentRotationDirection != RotationDirection.rotatingRight
             && internalAngleStorage < maxAngle) {
           //We aren't currently rotating towards the right & we aren't past the max.
                currentRotationDirection = RotationDirection.rotatingRight;
                //This will start the rotating and indirectly cancel any lingering rotation
                // the other direction.
                StartCoroutine ( RotateToMax ( RotationDirection.rotatingRight ) ) ;
           }
      }

      //This whole chunk works the same as the conditional above it.
      //Just in the other direction.
      if ( Input.GetKeyDown ( KeyCode.E ) ) {
           if ( currentRotationDirection != RotationDirection.rotatingLeft
             && internalAngleStorage > -maxAngle) {
                currentRotationDirection = RotationDirection.rotatingLeft;
                StartCoroutine ( RotateToMax (  RotationDirection.rotatingLeft ) ) ;
           }
      }
 
 }
 
 public IEnumerator RotateToMax (RotationDirection direction ) {

      //As long as the direction we're rotating is the same as the direction
      //we're give, keep going.
      while ( currentRotationDirection == direction ) {
           var deltaAngle = (int) direction * rotationSpeed * Time.deltaTime;
           //This will do Left vs. Right for us.
           transform.Rotate ( Vector3.forward * deltaAngle);
           internalAngleStorage += deltaAngle;
           //adjust the internal angle counter.
           if ( Mathf.Abs(internalAngleStorage) >= maxAngle  && Mathf.Sign (internalAngleStorage)  == (int)direction )
           //If we're at max...STOP.
                currentRotationDirection = RotationDirection.resting;
           yield return null;
           //wait a frame.  Do it again.
      }
 }

I think this will basically do what you're asking it to. I think I've done a pretty good job commenting on the code, but if you have any questions feel free to ask them. Basically we check for Input in Update() then offload the bulk of the work to another function.


EDIT

Okay, I've added in the middle ground ability. It's very similar to the original script. I'll go ahead and post it. Everything should work now.

 using UnityEngine;
 using System.Collections;
 
 public class TestRotate2 : MonoBehaviour {
 
     public enum RotationPosition {
          Left = -1 , 
          Center = 0, 
          Right = 1
     } 
      
     public float maxAngle = 30;
     //since you're rotating 30 degrees in both, we'll simplify everything and just say we can't rotate
     //more than 30 degrees in either direction
     public float tolerance = 1;
      
     public float rotationSpeed = 45;
     //It'll take 2 seconds to hit the extremes from the center.
      
     private RotationPosition currentRotation = RotationPosition.Center;
     //we're going to use an enum to store our current state.
     private float internalAngleStorage = 0;
     //THIS IS HOW WE ARE GOING TO AVOID THE 330 VS. -30 ISSUE
     //By storing the angle internally, we don't need to worry about the value unity
     //reports
      
     public void Update () {
         if ( Input.GetKeyDown ( KeyCode.Q ) ) {
          //Did the user press the button.
             if ( currentRotation != RotationPosition.Right) {
                   switch (currentRotation) {
                 case RotationPosition.Left:
                     StartCoroutine ( RotateToPosition ( RotationPosition.Center ) );
                     break;
                 case RotationPosition.Center:
                     StartCoroutine ( RotateToPosition ( RotationPosition.Right ) ); 
                     break;
                 }
             }
         }
      
          //This whole chunk works the same as the conditional above it.
          //Just in the other direction.
         if ( Input.GetKeyDown ( KeyCode.E ) ) {
              if ( currentRotation != RotationPosition.Left) {
                   switch (currentRotation) {
                 case RotationPosition.Right:
                     StartCoroutine ( RotateToPosition ( RotationPosition.Center ) );
                     break;
                 case RotationPosition.Center:
                     StartCoroutine ( RotateToPosition ( RotationPosition.Left ) ); 
                     break;
                 }
             }
         }
      
     }
      
     public IEnumerator RotateToPosition (RotationPosition targetRotation ) {
         currentRotation = targetRotation;
         var direction = Mathf.Sign ( (int)targetRotation * maxAngle - internalAngleStorage );
         var targetAngle = (int)targetRotation * maxAngle;
      
          //As long as the direction we're rotating is the same as the direction
          //we're give, keep going.
          while ( currentRotation == targetRotation ) {
               var deltaAngle = direction * rotationSpeed * Time.deltaTime;
               transform.Rotate ( Vector3.forward * deltaAngle);
               internalAngleStorage += deltaAngle;
               //adjust the internal angle counter.
               if ( Mathf.Abs(internalAngleStorage - targetAngle) < tolerance)
                      break;
               yield return null;
               //wait a frame.  Do it again.
          }
     }
 }
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 Vectorizing · Jul 22, 2013 at 12:04 AM 0
Share

First off it works perfectly, I really appreciate the time you spent working on this. however one change I had to make was this line in your code:

 private RotatingDirection currentRotationDirection = RotationDirection.resting;


the variable RotatingDirection was supposed to be RotationDirection I believe, I changed it to that and it worked.

Now 1 more question for you. How would I go about having it stop in between the 2 at zero degrees? In this case how do I make it stop at the resting position and then require the user to press Q or E to move to rotate to which ever they want?

So if i'm at 0 degrees and I push Q it goes left. Then if I push E it goes back to 0, and if I push E again it goes to the right?

Once again thank you very much!!!

avatar image Peter G · Jul 22, 2013 at 01:53 AM 0
Share

Yes that was a typo.

As far as adding a middle ground, it shouldn't be too hard to implement.

  1. Let's start with the easiest step. You'll want to change the angle check. Currently we stop moving if we're past either extrema. You're going to want to make it a tolerance problem. You'll want to stop moving when you get within 1-2 degrees of the desired position.

  2. You're going to want to slightly alter how the parameter works. Currently you pass a rotation direction to RotateTo$$anonymous$$ax(). What you're going to want to do is pass a target position ins$$anonymous$$d.

  3. From that you'll be able to figure out which direction you want to move based on where you are relative to the target. $$anonymous$$athf.Sign(destination angle - current angle) = rotationDirection

  4. You'll want to change the current rotation direction to the current rotation (i.e. left, right or centered). Either create a fourth value that represents you've reached the target and you need to stop, or make it a nullable type and set the value to null. You need to break the while loop somehow.

If you have any more questions, I'll do what I can to help. And if I get some time later I might be able to put it together. It should be fairly similar in design to what currently exists.

avatar image Vectorizing · Jul 22, 2013 at 03:35 AM 0
Share

Well I have been sitting here for awhile trying to figure this out, and im not sure what to do at all, im a bit confused at the moment.

avatar image Peter G · Jul 22, 2013 at 03:59 AM 0
Share

Okay I edited the post. It should work now.

avatar image Vectorizing · Jul 22, 2013 at 04:08 AM 0
Share

And just like that you fixed my problem. I was confused as to how I should add it to the enum and what number I was going to assign it (Centered = 2) because the deltaAngle used those numbers and I knew if I used 2 it would double the value and mess everything up, but you just went through and gave them totally different names and everything.

This script works flawlessly, and I really appreciate your time and help. I will mark the answer as solved.

Thanks!!!

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

17 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Shoot in the direction mouse is pointing 1 Answer

Local Euler Angles not Rotating GameObjects 1 Answer

Flip over an object (smooth transition) 3 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