Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Time.deltaTime not working

Discussion in 'Scripting' started by Kirasky, Apr 15, 2014.

  1. Kirasky

    Kirasky

    Joined:
    Apr 10, 2014
    Posts:
    11
    Hi, i'm a student and quite new to doing c# touch script for windows phone 8. I did a simple transform.translate to move according to the swipe direction and added Time.deltaTime. The problem is that instead of moving to the direction, its currently jumping to it. Any help would be highly appreciated.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class touchscript2 : MonoBehaviour
    5. {
    6.     public enum Swipe { Up, Down, Left, Right, UpLeft, UpRight, DownLeft, DownRight };
    7.     public float minSwipeLength = 200f;
    8.    
    9.     Vector2 firstPressPos;
    10.     Vector2 secondPressPos;
    11.     Vector2 currentSwipe;
    12.  
    13.     float tweakFactor = 0.5f;
    14.    
    15.     public static Swipe swipeDirection;
    16.    
    17.     public string debugInfo;
    18.     void OnGUI()
    19.     {
    20.         debugInfo = GUI.TextField (new Rect (10, 10, 200, 50), debugInfo, 50);
    21.     }
    22.  
    23.  
    24.     void Update ()
    25.     {
    26.         if (Input.touches.Length > 0)
    27.         {
    28.             Touch t = Input.GetTouch(0);
    29.            
    30.             if (t.phase == TouchPhase.Began)
    31.             {
    32.                 firstPressPos = new Vector2(t.position.x, t.position.y);
    33.             }
    34.            
    35.             if (t.phase == TouchPhase.Ended)
    36.             {
    37.                 secondPressPos = new Vector2(t.position.x, t.position.y);
    38.                 currentSwipe = new Vector3(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
    39.                
    40.                
    41.                 currentSwipe.Normalize();
    42.                
    43.                 debugInfo = currentSwipe.x.ToString() + " " + currentSwipe.y.ToString();
    44.                
    45.                 if (currentSwipe.y > 0  currentSwipe.x > 0 - tweakFactor  currentSwipe.x < tweakFactor) {
    46.                     swipeDirection = Swipe.Up;
    47.                     transform.Translate (new Vector2 (0,200*Time.deltaTime));
    48.                     debugInfo = "Up swipe";
    49.  
    50.                 } else if (currentSwipe.y < 0  currentSwipe.x > 0 - tweakFactor  currentSwipe.x < tweakFactor) {
    51.                     swipeDirection = Swipe.Down;
    52.                     transform.Translate (new Vector2 (0,-200*Time.deltaTime));
    53.                     debugInfo = "Down swipe";
    54.                    
    55.                 } else if (currentSwipe.x < 0  currentSwipe.y > 0 - tweakFactor  currentSwipe.y < tweakFactor) {
    56.                     swipeDirection = Swipe.Left;
    57.                     transform.Translate (new Vector2 (-200*Time.deltaTime,0));
    58.                     debugInfo = "Left swipe";
    59.                    
    60.                 } else if (currentSwipe.x > 0  currentSwipe.y > 0 - tweakFactor  currentSwipe.y < tweakFactor) {
    61.                     swipeDirection = Swipe.Right;
    62.                     transform.Translate (new Vector2 (200*Time.deltaTime,0));
    63.                     debugInfo = "Right swipe";
    64.  
    65.                 } else if (currentSwipe.y > 0  currentSwipe.x < 0 ) {
    66.                     swipeDirection = Swipe.UpLeft;
    67.                     transform.Translate (new Vector2 (-200*Time.deltaTime,200*Time.deltaTime));
    68.                     debugInfo = "Up Left swipe";
    69.  
    70.                 } else if (currentSwipe.y > 0  currentSwipe.x > 0 ) {
    71.                     swipeDirection = Swipe.UpRight;
    72.                     transform.Translate (new Vector2 (200*Time.deltaTime,200*Time.deltaTime));
    73.                     debugInfo = "Up Right swipe";
    74.  
    75.                 } else if (currentSwipe.y < 0  currentSwipe.x < 0 ) {
    76.                     swipeDirection = Swipe.DownLeft;
    77.                     transform.Translate (new Vector2 (-200*Time.deltaTime,-200*Time.deltaTime));
    78.                     debugInfo = "Down Left swipe";
    79.  
    80.                 } else if (currentSwipe.y < 0  currentSwipe.x > 0 ) {
    81.                     swipeDirection = Swipe.DownRight;
    82.                     transform.Translate (new Vector2 (200*Time.deltaTime,-200*Time.deltaTime));
    83.                     debugInfo = "Down Right swipe";
    84.                 }
    85.             }
    86.         }
    87.     }
    88. }
     
  2. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    Time.deltaTime doesn't make it move the distance over time, that needs to be done over multiple frames and in your case you can use Coroutines to do so.
     
  3. Kirasky

    Kirasky

    Joined:
    Apr 10, 2014
    Posts:
    11
    Ok thanks, i guess i misunderstood Time.deltaTime. Will try using the Coroutines and will update on the progress.
     
  4. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Time.deltaTime is the time that passed since the last frame.

    If you run at a fixed 30 frame per second, deltaTime will be 0.033 (33 millisecond).

    It's used to give object a proper speed. Let's say you want to move something 1 meter per second, you need to know when that second occur.
     
  5. Kirasky

    Kirasky

    Joined:
    Apr 10, 2014
    Posts:
    11
    So far no luck in trying to find a way to solve it. Tried Coroutines and its not working. I'm guessing its the lack of knowledge i have for coding. Can anyone help? Thanks in advance.
     
  6. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    Here's an example:
    Code (csharp):
    1.  
    2. public float speed=1f;
    3.  
    4. void Update () {
    5.     if (Input.GetKeyDown (KeyCode.Space)) {
    6.         StartCoroutine (MoveRightOneUnit ());
    7.     }
    8. }
    9.  
    10. IEnumerator MoveRightOneUnit () {
    11.     float lerp = 0;
    12.     float distance = 1; // example distance of 1 unit
    13.     float time = distance/speed;
    14.  
    15.     Vector3 startPos = transform.position;
    16.     Vector3 endPos = startPos+Vector3.right*distance;
    17.  
    18.     while (lerp < 1f) {
    19.         transform.position = Vector3.Lerp (startPos, endPos, lerp);
    20.  
    21.         lerp += Time.deltaTime/time;
    22.         yield return null;
    23.     }
    24.  
    25.     transform.position = endPos;
    26. }
    27.  
     
    Last edited: Apr 18, 2014
  7. Kirasky

    Kirasky

    Joined:
    Apr 10, 2014
    Posts:
    11
    Tested it out and its moving to the direction but im having the trouble of changing the distance of which it moves and the speed of it. Tried changing float distance to a higher value but still the distance is the same.
     
  8. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    Heh, looks like I never hooked up the distance variable to the actual code.

    I've updated it, though it would be a good learning exercise to try to figure out why it wasn't working.
     
  9. Kirasky

    Kirasky

    Joined:
    Apr 10, 2014
    Posts:
    11
    Sorry but my knowledge of coding is really terrible as i have no knowledge of C# few weeks ago. I only pick up bits and pieces due to time constrain. Have to finish designing + coding of game within 7 week while trying to juggle my other two 3d final year subjects. I tried adding *distance to end position but then it created the problem of delayed movement of the swipe after it. It will move the character to the end position before moving to the other direction. I tried changing the time and speed but it doesn't help. Is this due to the lerp? Thanks again
     
  10. Kirasky

    Kirasky

    Joined:
    Apr 10, 2014
    Posts:
    11
    So far this is what i have for the codes. Please correct me in the areas that i have made a mistake. Thank you

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class touchscript6 : MonoBehaviour
    6. {
    7.     public enum Swipe { Up, Down, Left, Right, UpLeft, UpRight, DownLeft, DownRight };
    8.     public float minSwipeLength = 200f;
    9.    
    10.     Vector2 firstPressPos;
    11.     Vector2 secondPressPos;
    12.     Vector2 currentSwipe;
    13.  
    14.     float tweakFactor = 0.5f;
    15.     public float speed = 1f;
    16.     public static Swipe swipeDirection;
    17.    
    18.     public string debugInfo;
    19.  
    20.  
    21.     void OnGUI()
    22.     {
    23.         debugInfo = GUI.TextField (new Rect (10, 10, 200, 50), debugInfo, 50);
    24.     }
    25.    
    26.     void  Update ()
    27.     {
    28.         if (Input.touches.Length > 0)
    29.         {
    30.             Touch t = Input.GetTouch(0);
    31.            
    32.             if (t.phase == TouchPhase.Began)
    33.             {
    34.                 firstPressPos = new Vector2(t.position.x, t.position.y);
    35.             }
    36.            
    37.             if (t.phase == TouchPhase.Ended)
    38.             {
    39.                 secondPressPos = new Vector3(t.position.x, t.position.y);
    40.                 currentSwipe = new Vector3(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
    41.                
    42.                
    43.                 currentSwipe.Normalize();
    44.                
    45.                 debugInfo = currentSwipe.x.ToString() + " " + currentSwipe.y.ToString();
    46.                
    47.                 if (currentSwipe.y > 0  currentSwipe.x > 0 - tweakFactor  currentSwipe.x < tweakFactor) {
    48.                     swipeDirection = Swipe.Up;
    49.                     StartCoroutine (MoveUp ());
    50.                     debugInfo = "Up swipe";
    51.  
    52.                 } else if (currentSwipe.y < 0  currentSwipe.x > 0 - tweakFactor  currentSwipe.x < tweakFactor) {
    53.                     swipeDirection = Swipe.Down;
    54.                     StartCoroutine (MoveDown ());
    55.                     debugInfo = "Down swipe";
    56.                    
    57.                 } else if (currentSwipe.x < 0  currentSwipe.y > 0 - tweakFactor  currentSwipe.y < tweakFactor) {
    58.                     swipeDirection = Swipe.Left;
    59.                     StartCoroutine (MoveLeft ());
    60.                     debugInfo = "Left swipe";
    61.                    
    62.                 } else if (currentSwipe.x > 0  currentSwipe.y > 0 - tweakFactor  currentSwipe.y < tweakFactor) {
    63.                     swipeDirection = Swipe.Right;
    64.                     StartCoroutine (MoveRight ());
    65.                     debugInfo = "Right swipe";
    66.  
    67.                 } else if (currentSwipe.y > 0  currentSwipe.x < 0 ) {
    68.                     swipeDirection = Swipe.UpLeft;
    69.  
    70.                     StartCoroutine (MoveLeft ());
    71.                     debugInfo = "Up Left swipe";
    72.  
    73.                 } else if (currentSwipe.y > 0  currentSwipe.x > 0 ) {
    74.                     swipeDirection = Swipe.UpRight;
    75.  
    76.                     StartCoroutine (MoveRight ());
    77.                     debugInfo = "Up Right swipe";
    78.  
    79.                 } else if (currentSwipe.y < 0  currentSwipe.x < 0 ) {
    80.                     swipeDirection = Swipe.DownLeft;
    81.  
    82.                     StartCoroutine (MoveLeft ());
    83.                     debugInfo = "Down Left swipe";
    84.  
    85.                 } else if (currentSwipe.y < 0  currentSwipe.x > 0 ) {
    86.                     swipeDirection = Swipe.DownRight;
    87.  
    88.                     StartCoroutine (MoveRight ());
    89.                     debugInfo = "Down Right swipe";
    90.                 }
    91.             }
    92.         }
    93.     }
    94.  
    95.     IEnumerator MoveUp () {
    96.  
    97.         float lerp = 0;
    98.         float distance = 5;
    99.         float time = distance*speed;
    100.  
    101.         Vector3 startPos = transform.position;
    102.         Vector3 endPos = startPos+Vector3.up*distance;
    103.  
    104.         while (lerp < 1f) {
    105.             transform.position = Vector3.Lerp (startPos, endPos, lerp);
    106.             lerp += Time.deltaTime/time;
    107.             yield return null;
    108.         }
    109.         transform.position = endPos;
    110.     }
    111.  
    112.     IEnumerator MoveDown () {
    113.        
    114.         float lerp = 0;
    115.         float distance = 5;
    116.         float time = distance/speed;
    117.        
    118.         Vector3 startPos = transform.position;
    119.         Vector3 endPos = startPos+Vector3.down*distance;
    120.        
    121.         while (lerp < 1f) {
    122.             transform.position = Vector3.Lerp (startPos, endPos, lerp);
    123.             lerp += Time.deltaTime/time;
    124.             yield return null;
    125.         }
    126.         transform.position = endPos;
    127.     }
    128.  
    129.     IEnumerator MoveLeft () {
    130.        
    131.         float lerp = 0;
    132.         float distance = 5;
    133.         float time = distance/speed;
    134.        
    135.         Vector3 startPos = transform.position;
    136.         Vector3 endPos = startPos+Vector3.left*distance;
    137.        
    138.         while (lerp < 1f) {
    139.             transform.position = Vector3.Lerp (startPos, endPos, lerp);
    140.             lerp += Time.deltaTime/time;
    141.             yield return null;
    142.         }
    143.         transform.position = endPos;
    144.     }
    145.  
    146.     IEnumerator MoveRight () {
    147.        
    148.         float lerp = 0;
    149.         float distance = 5;
    150.         float time = distance/speed;
    151.        
    152.         Vector3 startPos = transform.position;
    153.         Vector3 endPos = startPos+Vector3.right*distance;
    154.        
    155.         while (lerp < 1f) {
    156.             transform.position = Vector3.Lerp (startPos, endPos, lerp);
    157.             lerp += Time.deltaTime/time;
    158.             yield return null;
    159.         }
    160.         transform.position = endPos;
    161.     }
    162. }
     
    Last edited: Apr 18, 2014
  11. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    I've gone through your code a bit and I have some advice for you. I have only really been able to find one problem problem for sure (time = distance * speed in MoveUp() ), but this advice might help you by way of, writing the code to be more readable will help any small typos and errors stand out more easily. These aren't actually a functional problem, but mostly a "code readability" thing.

    This:
    Code (csharp):
    1.  
    2.          secondPressPos = new Vector3(t.position.x, t.position.y);
    3.  
    4.                 currentSwipe = new Vector3(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
    5.  
    is all unnecessary. You can directly subtract Vector3's, and Touch.position is a Vector2, which I (implicitly, I think) converts to a Vector3. So you can just do currentSwipe = t.position - firstPressPos; Like I said, it's not your problem, but it could've been; if there's more repetitive typing involved in writing code, there's more likelihood that you'll type the wrong thing on autopilot. In addition to being more annoying to read and write.

    Similarly, this:
    Code (csharp):
    1.  
    2.                 debugInfo = currentSwipe.x.ToString() + " " + currentSwipe.y.ToString();
    3.  
    You could replace with debugInfo = currentSwipe.ToString()

    And this:
    Code (csharp):
    1.  
    2. currentSwipe.Normalize();
    3.  
    is unnecessary, and slow. If anything, it removes useful information in this kind of use case. Normalize is one of those operations you should get in the habit of not using unless it's really needed.

    On to the movement coroutines: you should really combine all those coroutines into one function, and send it a parameter. One function is easier to maintain than 4, or 8. Case in point: one of your functions says time = distance * speed, and the other three say time = distance / speed. So one of these four is going to behave DRASTICALLY different from the others. This sort of thing can crop up when you have many functions like this.

    Code (csharp):
    1.  
    2.     IEnumerator Move (Vector3 offset) {
    3.  
    4.  
    5.  
    6.         float lerp = 0;
    7.  
    8.         float distance = 5;
    9.  
    10.         float time = distance/speed;
    11.  
    12.  
    13.  
    14.         Vector3 startPos = transform.position;
    15.  
    16.         Vector3 endPos = startPos+offset;
    17.  
    18.  
    19.  
    20.         while (lerp < 1f) {
    21.  
    22.             transform.position = Vector3.Lerp (startPos, endPos, lerp);
    23.  
    24.             lerp += Time.deltaTime/time;
    25.  
    26.             yield return null;
    27.  
    28.         }
    29.  
    30.         transform.position = endPos;
    31.  
    32.     }
    33.  
    I also have a recommendation for easily readable coroutine code. It's something I use in nearly every coroutine I write, because it's consistent, concise, reliable, and easy to understand. And that is: the timed "for" loop. The basic form of it is:

    Code (csharp):
    1.  
    2. for (float t=0f; t<duration; t += Time.deltaTime) {
    3. float lerpValue = t/duration;
    4. //your frame-by-frame code goes here
    5. yield return null;
    6. }
    7.  
    Functionally it's basically the same as your while loop, it just gets all the "same-in-every-situation" sort of functionality out of the way in one highly copy-paste-able block of code, reducing the likelihood of errors creeping in when you write a new coroutine.

    Taking advantage of this, your Move coroutine could look like:
    Code (csharp):
    1.  
    2. IEnumerator Move(Vector3 offset) {
    3.  
    4. Vector3 startPos = transform.position;
    5. Vector3 endPos = startPos + offset;
    6.  
    7. float duration = offset.magnitude / speed;
    8.  
    9. for (float t=0f; t<duration; t += Time.deltaTime) {
    10. float lerpValue = t/duration;
    11. transform.position = Vector3.Lerp (startPos, endPos, lerp);
    12.  
    13. yield return null;
    14. }
    15. transform.position = endPos;
    16. }
    17.  
    There's one more problem with this function, and it's possible this is the "delayed movement" you describe: if you swipe up, then left, before the thing has finished its upward movement, then the "move up" coroutine is still running and the "move left" coroutine gets started anyway, and you get both of them fighting to set the position. Here's how I usually solve that problem:

    Code (csharp):
    1.  
    2. private int currentMoveFunctionCounter = 0;
    3. IEnumerator Move(Vector3 offset) {
    4. currentMoveFunctionCounter++;
    5. int myCounter = currentMoveFunctionCounter;
    6.  
    7. Vector3 startPos = transform.position;
    8. Vector3 endPos = startPos + offset;
    9.  
    10. float duration = offset.magnitude / speed;
    11.  
    12. for (float t=0f; t<duration; t += Time.deltaTime) {
    13. float lerpValue = t/duration;
    14. transform.position = Vector3.Lerp (startPos, endPos, lerp);
    15. if (currentMoveFunctionCounter != myCounter) break;
    16. yield return null;
    17. }
    18. if (currentMoveFunctionCounter == myCounter) transform.position = endPos;
    19. }
    20.  
    This way, you can interrupt a coroutine in progress by simply incrementing currentMoveFunctionCounter (or, rather, you can make it interrupt itself) - the "break" will make it jump out of the for loop.

    So, I don't know if I've solved your problem, but I hope so. And hopefully helped your general code structure in the process?
     
  12. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    You can also use StopCoroutine or StopAllCoroutines.
     
  13. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    Issues with that:

    1) In this context, they also stop the coroutine you're calling it from.
    2) If a coroutine needs to do any kind of "cleanup", StopCoroutine gives it no chance to do that.
    3) StopCoroutine(string) only works on coroutines that were started using StartCoroutine(string).
    4) StopAllCoroutines works on StartCoroutine(Method())-called coroutines, but if any other coroutines are running on the object that you DON'T want to halt, tough noogies.

    The incrementing-member technique works in pretty much every context. A slight variation on it even allows you to write coroutines that patiently wait for other coroutines to finish before going about their business, which is amazing for almost anything you'd want to use coroutines for.

    For those reasons, I've made a habit of just NEVER using Stop*Coroutine methods unless I'm in an extreme rush.
     
  14. Kirasky

    Kirasky

    Joined:
    Apr 10, 2014
    Posts:
    11
    Thank you guys so much for all your tips and tricks. I got the object to move how i want now. Just finding a way now to move it diagonally as well. Again i really appreciate the time that you guys put in to help.
     
  15. Kirasky

    Kirasky

    Joined:
    Apr 10, 2014
    Posts:
    11
    Btw, is coroutine causing my background music to lag? I used a blank scene with the object attached with the script. I tried mp3 and wave for the audio format, turn off the 3d sound and force to mono as well. Changing load type and compression also did not help.
     
  16. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    It's probably unrelated. How do you play your music? And what do you mean by "lag" - the music stutters, or it takes time to begin playing, or what?
     
  17. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    Are you trying to create 1-to-1 movement between your transform and the touch? or is this a sort of grid-based movement or something, where moving by (X) units at a time is important?
     
  18. Kirasky

    Kirasky

    Joined:
    Apr 10, 2014
    Posts:
    11
    Sorry i was referring to the background song stuttering. I used audio.Play(); and yield WaitForSeconds (audio.clip.length);. Btw i'm using windows phone lumia 925 so that might be the problem. I'm creating a slide to move the character with the delay so when the player lifts the finger after the gesture then it moves according to the gesture direction. Think of it as a flying game where you control the direction of the aircraft by swiping left, right, up and down.
     
    Last edited: Apr 22, 2014
  19. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    The stuttering could be many things, from an error in the way or timing that the audio is being controlled, to processor overload. I don't think I can help diagnose that one over the forums.

    For diagonals: is it important to do pure diagonals (e.g. 8 and only 8 directions) or can the player swipe in any direction? If the latter, this math is pretty easy: in place of all those if statements, you want to normalize the currentSwipe vector, multiply it by the distance you're moving, then pass that into the Move() function. (One of those times normalizing a vector makes sense!)

    If it does need to be only 8 directions, then… You could do some angle math (use Mathf.Atan2 to get the angle of the swipe, convert to degrees, round it to the nearest 45, then use sin and cos to convert the rounded angle back to a vector, and pass that into Move() ).
     
  20. Kirasky

    Kirasky

    Joined:
    Apr 10, 2014
    Posts:
    11
    I searched around and other people has the same problem with the lumia phone. So far none of the solutions suggested worked. The character is supposed to move in 8 directions but moving in any directions should be fine as well. It would make the game more dynamic. I've tried to alter that but the closes i could get is having the character directly following the finger. Some examples on how i can do it is highly appreciated. To be honest im very short on time and i have not much time to really learn C# thoroughly. I still have the graphical side to handle like the animations using animator which is new to me. Thanks again