Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 MachCUBED · Feb 01, 2013 at 11:31 PM · rotationvector3mathmathf.lerp

Unable to fully rotate GameObject on tap

Hi guys,

I've got this bit of code in a script named TapRotationLogic.cs attached to a wall:

 // Called when tapped
     void OnTap () {

         Debug.Log("Tapped to rotate");
         Quaternion newRot = transform.rotation;
         newRot.y += Mathf.Lerp(0.0f, 45.0f, 2.0f);
         transform.rotation = newRot;
         
     }

The above method is called from TBTap.cs, which is set to call the OnTap method. However, even though OnTap is getting called (I can tell from the debugging console), the wall is only rotating in a choppy manner a few degrees, back and forth. And that's if it even bothers to rotate at all, despite the relevant function firing perfectly fine.

The wall should rotate exactly 45 degrees relative to the y axis on every tap, and it should rotate smoothly.

What am I doing wrong? Please help.

MachCUBED

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 iwaldrop · Feb 01, 2013 at 11:41 PM 1
Share

First off, if you read the documentation, you'll see that the maximum value the Lerp function wants is a 1. Secondly, unless you're lerping over time then you're going to get one result, whatever t is equal to.

2 Replies

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

Answer by Wolfram · Feb 02, 2013 at 02:07 AM

You don't mess with the components of Quaternions directly. They are sufficiently unrelated to angles. Never set or query something like transform.rotation.y directly, it won't help you.

Read up on how to use a Quaternion in the docs, or what it is on Wikipedia, if you're interested.

Convert to and from a Quaternion using convenience functions:

 Vector3 angles=myquaternion.eulerAngles;
 angles.y+=45;
 myquaternion=Quaternion.Euler(angles);

EDIT: or, in case of transform.rotation, use transform.eulerAngles instead, for both query and assignment.

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 iwaldrop · Feb 02, 2013 at 02:17 AM 0
Share

Ha! I was just about to come on here and correct myself...leave it to you to beat me to it! ;)

avatar image MachCUBED · Feb 02, 2013 at 04:24 AM 0
Share

I modified the code to not modify the Quaternion components directly and came up with this:

 IEnumerator RotateGameObject (float speed)
     {
         Debug.Log("Tapped to rotate");
         Quaternion myQuaternion = transform.rotation;
         
         Vector3 angles = myQuaternion.eulerAngles;
      
         while (transform.rotation.y < myQuaternion.y) 
         {
             angles.y = $$anonymous$$athf.Lerp(angles.y, 45, speed);
             myQuaternion = Quaternion.Euler(angles);
             transform.rotation = myQuaternion;
             yield return 0;
         }
     }

Now the GameObject won't rotate at all.

avatar image iwaldrop · Feb 02, 2013 at 04:58 AM 0
Share

Just set the eulerAngles of your transform to angles ins$$anonymous$$d of creating a Quaternion.

 while (transform.rotation.y < myQuaternion.y)
 {
     angles.y = $$anonymous$$athf.Lerp(angles.y, 45, speed);
     transform.eulerAngles = angles;
     yield return 0;
 }
avatar image Wolfram · Feb 02, 2013 at 11:22 AM 1
Share

You are still accessing the quaternion:

 while (transform.rotation.y < myQuaternion.y)

Also note that using Lerp with a constant/small term such as "speed", you are creating an accelerated motion, a "spring" effect, where you start fast, and the rotation become slower the closer you get to the target value (similar to an "ease out"). For smooth constant speed, use Lerp as it's original intended, and as @vonni demonstrated (although all Lerp examples in the docs unfortunately are very bad examples, since there is no time control whatsoever.

 Vector3 angles=transform.eulerAngles;
 float startTime=Time.time;
 float startAngle=angles.y;
 float endAngle=startAngle+45; // -45 for left turn
 while(duration>=Time.time-startTime){
     angles.y=$$anonymous$$athf.LerpAngle(startAngle,endAngle,(Time.time-startTime)/duration);
     transform.eulerAngles=angles;
     yield return null;
 }

Also, for angles, always use LerpAngle, to avoid wraparound problems at 360 degrees.

Another mistake is your code will always rotate towards 45 degrees absolute, not by 45 degrees. I fixed that, too. Browse through Unity Answers, there are tons of questions and solutions on how to rotate an object from A to B. Also consider using the free iTween, which can do ease in, ease out, and many other things.

avatar image MachCUBED · Feb 02, 2013 at 06:51 PM 0
Share

Wolfram has solved it! The final code is:

 IEnumerator RotateGameObject (float duration)
     {
         Debug.Log("Tapped to rotate");
         Vector3 angles = transform.eulerAngles;
         float startTime = Time.time;
         float startAngle = angles.y;
         float endAngle = startAngle + 45; // -45 for left turn
         
         while(duration >= Time.time - startTime)
         {
             angles.y = $$anonymous$$athf.LerpAngle(startAngle,endAngle,(Time.time - startTime) / duration);
             transform.eulerAngles = angles;
             yield return null;
         }
     }

Thanks everyone!

avatar image
0

Answer by Vonni · Feb 01, 2013 at 11:53 PM

function OnTap only executes once. You only rotate it what it would on 1 game frame.

and as iwaldrop said, the "t" of Mathf.Lerp (which is 2.0f in your case) controls the PROGRESS of the lerp.

So what you want to do is to setup a coroutine (look it up). And then run from 0 - 1 in t, where 0 is the start and the value one being the targeted rotation.

like shown in the docs:

 // Fades from minimum to maximum in one second
 
 var minimum = 10.0;
 var maximum = 20.0;
 
 function Update () {
     transform.position = Vector3(Mathf.Lerp(minimum, maximum, Time.time), 0, 0);
 }

notice that this works because it is inside update(which executes 1 time per game frame. And because of Time.time which will make this lerp finish after 1 second.

But you want it to happen OnTap, so call a COROUTINE function from there.

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 MachCUBED · Feb 02, 2013 at 01:48 AM 0
Share

I tried implementing a coroutine, so that the code looks like this:

 public class TapRotationLogic : $$anonymous$$onoBehaviour {
 
     // Use this for initialization
     void Start () {
     
     }
     
     // Called when tapped
     void OnTap () {
         
         StartCoroutine("RotateGameObject", Time.time);
         
     }
     
     IEnumerator RotateGameObject (float timeInterval)
     {
         Debug.Log("Tapped to rotate");
         Quaternion newRot = transform.rotation;
         newRot.y += $$anonymous$$athf.Lerp(0.0f, 45.0f, timeInterval);
         transform.rotation = newRot;
         yield return new WaitForFixedUpdate();
     }
 }

But I still have the same problem. Bummer.

avatar image iwaldrop · Feb 02, 2013 at 02:01 AM 0
Share

try...

 IEnumerator RotateGameObject (float speed)
 {
     Debug.Log("Tapped to rotate");
     Quaternion targetRotation = transform.rotation;
     targetRotation.y += 45;

     while (rotation.y < targetRotation.y) 
     {
         transform.rotation = $$anonymous$$athf.Lerp(transform.rotation, targetRotation, speed);
         yield return 0;
     }
 }
avatar image MachCUBED · Feb 02, 2013 at 02:10 AM 0
Share

The above code had a compile error, and my efforts to fix the errors resulted in the following code:

 IEnumerator RotateGameObject (float speed)
     {
         Debug.Log("Tapped to rotate");
         Quaternion targetRotation = transform.rotation;
         targetRotation.y += 45;
         
         Quaternion newRot = transform.rotation;
      
         while (transform.rotation.y < targetRotation.y) 
         {
             newRot.y = $$anonymous$$athf.Lerp(transform.rotation.y, targetRotation.y, speed);
             transform.rotation = newRot;
             yield return 0;
         }
     }

And I still have the same problem. Bummer.

avatar image Wolfram · Feb 02, 2013 at 02:31 AM 0
Share

Have you read my answer by now?

avatar image Vonni · Feb 02, 2013 at 12:33 PM 0
Share

hehe, dont use Time.time! By the time you proably tap the screen the value of Time.time is over 1, so it will never rotate smoothly. Time.time just keep going up and up and is the time spendt in game.You also have nothing in your coroutine that makes it keep going for more than 1 frame. You need a while statement or something to keep it executing the coroutine until t = 1; That will work, gl.

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

12 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

Related Questions

Rotate a Vector3 direction 3 Answers

Convert local forward into world vector 1 Answer

How to compute the change in vector when it's referential vector changes? 0 Answers

Workaround for Quaternion.eulerAngles 360 Degree Limit? 1 Answer

Applying force with respect to angle with the ground? 1 Answer


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