Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

C# Object instantly rotates instead of rotating slowly

Discussion in 'Scripting' started by Larpushka, Jul 14, 2015.

  1. Larpushka

    Larpushka

    Joined:
    Jan 6, 2015
    Posts:
    214
    What gives? I added a float speed and the Time.deltaTime

    The idea is for it to rotate 90 degrees every click on the X axis. I want it to happen fast but not instantly.


    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class RotObject : MonoBehaviour {
    6.     public float speed = 1f;
    7.     void OnMouseDown () {
    8.         transform.Rotate((90f),(0),(0) * (speed * Time.deltaTime));
    9.     }
    10.  
    11. }
    12.  
    13.  
     
    Last edited: Jul 14, 2015
  2. tedthebug

    tedthebug

    Joined:
    May 6, 2015
    Posts:
    2,570
    I can't check as I have no PC at the moment but try putting the vector stuff in brackets rather than each vector #
    1. transform.Rotate((90f,0,0) * (speed * Time.deltaTime));
     
  3. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,850
    Rotate does not perform animation. You are multiplying the third value y by 0 so its a bit pointless.

    OnMouseDown is called once. If you want to animate it then try lerping the value. OnMouseDown can be a coroutine so you could still do it in the same place.
     
  4. kemar

    kemar

    Joined:
    Nov 4, 2014
    Posts:
    15
    Hi,

    I'm not sure i understand your purpose but i will try to respond...

    1) In your exemple the object will turn instantly for 90°. This is why you saw no rotation.
    2) Why this " (0)*(speed*Time.deltaTime) " ? you know 0 * X will always give you a 0 as result, this operation is useless.


    if you want to rotate your object slowly use the Update loop, like this
    Code (CSharp):
    1.  
    2. public float speed = 0.1f;
    3.  
    4. void Update()
    5. {
    6. transform.Rotate((5f),(0),(0));
    7. }
    or if you want to rotate your object when the player click, use this code
    Code (CSharp):
    1.   public float speed = 1f;
    2.     void OnMouseDown () {
    3.         transform.Rotate((30f),(0),(0));
    4.     }

    Sorry for my bad english
     
    Last edited: Jul 14, 2015
  5. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,850
    Try this
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class RotObject : MonoBehaviour
    6. {
    7.     public float speed = 1f;
    8.     public Vector3 rotAmount = new Vector3(90,0,0);
    9.  
    10.     IEnumerator OnMouseDown () // A couroutine can be run each frame so we can do animation.
    11.     {
    12.         float endTime = Time.time + speed; // When to end the coroutine
    13.         float step = 1f/speed; // How much to step by per sec
    14.         var fromAngle = transform.eulerAngles; // start rotation
    15.         var targetRot = transform.eulerAngles + rotAmount; // where we want to be at the end
    16.         float t = 0; // how far we are. 0-1
    17.         while(Time.time <= endTime)
    18.         {
    19.             t += step * Time.deltaTime;
    20.             transform.eulerAngles = Vector3.Lerp(fromAngle, targetRot, t);
    21.             yield return 0;
    22.         }
    23.     }
    24. }
    25.  
     
  6. Larpushka

    Larpushka

    Joined:
    Jan 6, 2015
    Posts:
    214
    Thank you Karl, but I get "the reference script for this behavior is missing".

    Why do you think I don't see the rotation? I do. My object rotates fine, just instantly.

    Why this " (0)*(speed*Time.deltaTime) " ? you know 0 * X will always give you a 0 as result, this operation is useless.

    That's why I have the "90" there

    transform.Rotate((90f),(0),(0)*(speed*Time.deltaTime));

    . If I could isolate the "90" it would be great.

    I don't want it to rotate instantly, I want it to rotate slowly till it reaches its "destination angle".
     
  7. gavinb80

    gavinb80

    Joined:
    Nov 4, 2012
    Posts:
    96
    I think Kemars point is, its happening instantly, you are not seeing a transition from start to finish as you want, and this is because you are just setting the rotation to 90f and multiplying the last value (which will have no impact)
     
  8. Larpushka

    Larpushka

    Joined:
    Jan 6, 2015
    Posts:
    214
    That's exactly my question...how is it possible to make it slowly rotate?


    Karl.Jones...THANK YOU VERY MUCH! I just had the name of the class wrong. Your script works :) I'll need to learn how you did it now ^^
     
  9. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,850
    Glad it helps.

    A little advice:

    Code (csharp):
    1. transform.Rotate((90f),(0),(0)*(speed*Time.deltaTime));
    In this function you are setting 3 values, x, y, z.
    X is 90, y is 0 and z is 0 multiplied by speed * time which will always give you 0. It looks like you have confused this with some other code.
    The rotate function does not apply animation, it sets the value once. To animate we need to gradually move the rotation over time which is what my code does. Each frame we move the rotation a little but closer to the target, Time.deltaTime is the time it takes to complete a single frame, we use this so our animation is not frame rate dependent. If your machine was running at 60fps then the while loop will loop about 60 times in total. Thats 60 small rotations to get the effect you wanted.
     
  10. Larpushka

    Larpushka

    Joined:
    Jan 6, 2015
    Posts:
    214
    Yea I just figured it makes more sense to do it without animation, so that's why I just prefered to use the inherit unity transform functions.

    Although it seems the second click I do rotates the cube back and it strangely becomes -5.008956e-06 degrees. I can't really understand from your code where it's coming from, but I did add a modulus so it will rotate if it's divisible by 90 degrees (otherwise I can mess the rotation up by clicking on it before it finishes the 90 degrees rotation). I also changed the "var" from "Vector3"... "var" seems a pretty weird choice when you're coding in C#.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Rot : MonoBehaviour
    5. {
    6.     public float speed = 1f;
    7.     public Vector3 rotAmount = new Vector3(90,0,0);
    8.    
    9.     IEnumerator OnMouseDown () // A couroutine can be run each frame so we can do animation.
    10.     {
    11.         if (transform.rotation.eulerAngles[0] % 90 == 0) {
    12.             float endTime = Time.time + speed; // When to end the coroutine
    13.             float step = 1f / speed; // How much to step by per sec
    14.             Vector3 fromAngle = transform.eulerAngles; // start rotation
    15.             Vector3 targetRot = transform.eulerAngles + rotAmount; // where we want to be at the end
    16.             float t = 0; // how far we are. 0-1
    17.             while (Time.time <= endTime) {
    18.                 t += step * Time.deltaTime;
    19.                 transform.eulerAngles = Vector3.Lerp (fromAngle, targetRot, t);
    20.                 yield return 0;
    21.             }
    22.         }
    23.     }
    24. }
     
  11. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,850
    Sounds like a little imprecision is creeping in. Its not really an issue as that value is tiny(-0.000005008956). Try snapping the value after the while loop to be sure it reached the target.

    Code (csharp):
    1.  
    2.   yield return 0;
    3. }
    4. transform.eulerAngles = targetRot;
    https://msdn.microsoft.com/en-us/library/bb383973.aspx

    You could also round the final vectors like this.
    var is perfectly fine in C#, its actually a lot nicer to work with ;)