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
0
Question by jakejolli · Mar 25, 2014 at 02:26 AM · rotationjavascriptquaternioneuleranglespuzzle

Smooth rotation in 90° increments

I have a puzzle in my game where there is a painting on a wall. The painting is broken up into a 4x6 grid of cubes (only one face of each is visible), and each cube is rotated on the x axis so that the image is scrambled.

The goal of the puzzle is to rotate each of the pieces until the picture is properly formed.

I know how to make the puzzle work, but not exactly the way I wanted to.

I was trying to make it so that each time a cube was clicked, it rotated 90° a second and stopped at each 90° increment.

Of course, Euler angles are all funky so I was having a hard time getting it to work properly, so I just have them instantly rotating 90° each click.

The code I was using while trying to make a smooth rotation is as follows:

  var rotationState: boolean = false;
     
     function OnMouseDown(){
         rotationState = true;
     }
     
     function Update () {    
         if (rotationState == true && transform.eulerAngles.x >=0 && transform.eulerAngles.x < 90){
             transform.Rotate(90 * Time.deltaTime, 0, 0);
             if (transform.eulerAngles.x >= 90){
                 rotationState = false;
             }
         } else if (rotationState == true && transform.eulerAngles.x >=90 && transform.eulerAngles.x < 180){
             transform.Rotate(90 * Time.deltaTime, 0, 0);
             if (transform.eulerAngles.x >= 180){
                 rotationState = false;
             }
         } else if (rotationState == true && transform.eulerAngles.x >= 180 && transform.eulerAngles.x < 270){
             transform.Rotate(90 * Time.deltaTime, 0, 0);
             if (transform.eulerAngles.x >= 270){
                 rotationState = false;
             } 
         } else if (rotationState == true && transform.eulerAngles.x >=270 && transform.eulerAngles.x < 360){
             transform.Rotate(90 * Time.deltaTime, 0, 0);
             if (transform.eulerAngles.x >= 360){
                 rotationState = false;
             }
         }
     }

The code worked for the first two clicks, and then the rotations started to get strange.

Does anyone have any idea how I can achieve the desired effect?

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

1 Reply

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

Answer by robertbu · Mar 25, 2014 at 03:26 AM

There are lots of ways to do what you want in Unity. Here is one. It requires that you set 'vCurr' to the starting rotation in the Inspector.

 #pragma strict
 
 var speed = 90;
 var vCurr : Vector3 = Vector3.zero;
 
 private var vNew  : Vector3 = Vector3.zero;
 
 function Start() {
     transform.eulerAngles = vCurr;
     vNew = vCurr;
 }
 
 function Update() {
     vCurr = Vector3.MoveTowards(vCurr, vNew, speed * Time.deltaTime);
     transform.eulerAngles = vCurr;
 }
 
 function OnMouseDown() {
     if (vCurr == vNew) 
         vNew.x += 90.0;
 }

Here is a second one. It is a relative rotation using Quaternions. It is a bit harder to understand than the first one, but it does not require setting the rotation in the inspector.

 #pragma strict

 var speed : float = 90.0;
 private var qTo : Quaternion;
 
 function Start() {
     qTo = transform.rotation;
 }
 
 function Update () {
     transform.rotation = Quaternion.RotateTowards(transform.rotation, qTo, speed * Time.deltaTime);
 }
 
 function OnMouseDown() {
     if (transform.rotation == qTo) 
         qTo = Quaternion.AngleAxis(90.0, Vector3.right) * qTo;
 
 }
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 jakejolli · Mar 25, 2014 at 07:43 PM 0
Share

Both work perfectly! Thank you!

I would like to use something similar to the first example you've provided, but I HATE using code that I don't fully understand.

I fully understand everything except for the Vector3.$$anonymous$$oveTowards.

The documentation makes it seem like this is generally used for movement, not rotation. Could you let me know if the following explanation is correct, and clarify if not?

Vector3.$$anonymous$$oveTowards returns a Vector3 value that is equal to the current rotation/position incremented by speed Time.deltaTime. However, if the value to be returned by Vector3.$$anonymous$$oveTowards exceeds the target value passed to* Vector3.$$anonymous$$oveTowards, the target value will be returned ins$$anonymous$$d.

By changing vCurr to Vector3.$$anonymous$$oveTowards(vCurr, vNew, speed * Time.deltaTime) each frame and setting the object's rotation equal to vCurr, a smooth rotation effect is achieved.

Is my understanding at least somewhat sound?

Also, you mentioned that the second script example doesn't require that I initialize vCurr in the Inspector.

Would the following modified version of your first script also do the trick, or is there a flaw I'm not seeing? (Lines 4 and 9 have been modified)

 #pragma strict
  
 var speed = 90;
 private var vCurr : Vector3 = Vector3.zero;
  
 private var vNew  : Vector3 = Vector3.zero;
  
 function Start() {
     vCurr = transform.eulerAngles;
     vNew = vCurr;
 }
  
 function Update() {
     vCurr = Vector3.$$anonymous$$oveTowards(vCurr, vNew, speed * Time.deltaTime);
     transform.eulerAngles = vCurr;
 }
  
 function On$$anonymous$$ouseDown() {
     if (vCurr == vNew) 
        vNew.x += 90.0;
 }

Thanks a bunch!

avatar image robertbu · Mar 25, 2014 at 08:22 PM 0
Share

What you are trying to do with the script in the second comment has an issue. You are reading eulerAngles:

 vCurr = transform.eulerAngles;

The problem is that there are multiple euler angle respresentations for any given physical rotation, and Unity may elect to give you one you don't expect. For example, do this in a test script:

  transform.eulerAngles = Vector3(180,0,0);
  Debug.Log(transform.eulerAngles);

The output will be (0,180,180). This is not the value you expect. The change in representation would result in your cube rotating the opposite way you expect.

As for the first part of your comment, your understanding is somewhat sound.

avatar image jakejolli · Mar 25, 2014 at 11:02 PM 0
Share

Ah, I see. I can tell these Euler Angles are going to take some getting used to. I'm fairly new to Unity (a month or so), and you seem well versed. Is there a particular resource you might suggest looking at to boost my knowledge?

Thanks again.

avatar image robertbu · Mar 25, 2014 at 11:43 PM 0
Share

Sorry I don't have a resource for you. $$anonymous$$ost of what I've learned is either through making my own mistakes or by reading about other's mistakes on this list. As a general rule, treat eulerAngles as write-only. If your object is only rotated around either 'y' or the 'z' (single axis rotation), then eulerAngles is safe to read. But not the 'x' axis. If you want to automate the 'x' axis for the first script, you could do it by using $$anonymous$$athf.Atan2() to calculate the angle, or you could compare (Vector3.Angle() or Vector3.Dot()) the transform.forward against the world forward, down, back and up axes.

avatar image jakejolli · Mar 25, 2014 at 11:52 PM 0
Share

Good to know!

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

20 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 avatar image avatar image avatar image

Related Questions

How to get Angle float of specific axis.(Turret clamping related). 2 Answers

When applying a 90 degree rotation to Euler Angles, it is over/undershooting sometimes.. 2 Answers

new Array storing rotations 1 Answer

[OAFAT]Why does transform.rotation.x = 45 not work 3 Answers

c# modify only one axis of a quaternion 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