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. Dismiss Notice

Confused about Time.deltaTime

Discussion in 'Scripting' started by JakobRW, Aug 7, 2016.

Thread Status:
Not open for further replies.
  1. JakobRW

    JakobRW

    Joined:
    Aug 7, 2016
    Posts:
    4
    So I'm trying to make a sort of target that appears in front of the player, to show how long the kick will be. But it keeps stopping at different positions, and I'm pretty sure it has something to do with Time.deltaTime but I don't know how I'd go about fixing it. Any help would be immensely appreciated. Below is the code for the target.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerKickEffect : MonoBehaviour {
    5.  
    6.     public PlayerMovement player;
    7.     public bool beforeKick;
    8.  
    9.     void Start () {
    10.         GetComponent<SpriteRenderer>().enabled = false;
    11.     }
    12.    
    13.     void Update () {
    14.  
    15.         if (Input.GetKeyDown (KeyCode.X) && !beforeKick && !player.kick)
    16.         GetComponent<SpriteRenderer>().enabled = true;
    17.  
    18.         if (Input.GetKey (KeyCode.X))
    19.             beforeKick = true;
    20.  
    21.         if (Input.GetKeyUp (KeyCode.X))
    22.         {
    23.             beforeKick = false;
    24.             GetComponent<SpriteRenderer>().enabled = false;
    25.             transform.localPosition = new Vector2 (0, 0);
    26.         }
    27.  
    28.         if (beforeKick && player.kickLength > 0 && player.kickLength < 10)
    29.         {
    30.             if (player.transform.localScale.x > 0)
    31.                 transform.Translate (4 * Time.deltaTime, 0, 0);
    32.             if (player.transform.localScale.x < 0)
    33.                 transform.Translate (-4 * Time.deltaTime, 0, 0);
    34.         }
    35.  
    36.         if (Input.GetKeyDown (KeyCode.A))
    37.             Debug.Log (transform.localPosition);
    38.     }
    39. }
    40.  
     
  2. ladyonthemoon

    ladyonthemoon

    Joined:
    Jun 29, 2015
    Posts:
    236
    Why do you use Time.deltaTime? Multiplying the translate movement by Time.deltaTime will stop the movement after "The time in seconds it took to complete the last frame...". If the last frame took, 1/100 of a second to complete, the movement will stop after 1/100 of a second and, most probably, never complete.

    (At least, that's how I understand it.) :)
     
  3. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,738
    not exactly Update is called every frame, deltatime is the time it takes a frame to update in seconds, so multiply his -4 * deltaTime, is scaling his -4 down, so the action of translating -4 units on the x happens over 1 full second.
     
    Bunny83 likes this.
  4. JakobRW

    JakobRW

    Joined:
    Aug 7, 2016
    Posts:
    4
    I use Time.deltaTime so that the character won't move different distances depending on the framerate... But clearly I haven't managed to accomplish that task.
     
  5. hawksprite

    hawksprite

    Joined:
    Dec 24, 2012
    Posts:
    11
    Okay.. so let me start by saying that Time.Delta is not your problem here. I just think it's application is in the wrong place.

    So if what I'm understanding is correct you have a player character. Lets say at 10,10,0. And when they hold X the strength of the kick builds up to a max of 10. Depending on the strength you want to show a target of where letting go of X would do at that given moment.

    There are two key pieces of information here that you want to not be different if their frame varies. How fast the player moves and how fast the kick strength builds up.

    But not necessarily where you're rendering the sprite for the target.

    Your approach in this regard is a little off. You should start by just assuming that the kick power will always be 5. And work out how you would like to calculate what distance 5 power means for the kick. Then you can have holding X increase the kick power by a certain amount affected by time delta. This way X goes up by 1 ever real world second. And not 1 every 30 frames. Otherwise, someone running at 60 FPS would get double the kicking power which could lead to balancing issues.

    Consider the following (Keep in mind this won't directly work for your case, its just an example):

    Code (csharp):
    1.  
    2. float currentKickingPower = 0;
    3. SpriteRenderer sprite;
    4.  
    5. void Start(){
    6.     sprite = GetComponent<SpriteRenderer>();
    7. }
    8.  
    9. void Update(){
    10.  
    11.     if (Input.GetKeyDown(KeyCode.X)){
    12.         sprite.enabled = true;
    13.         currentKickingPower += 1.0f * Time.deltaTime;
    14.  
    15.  
    16.         // Determine where the player is
    17.         Vector3 targetLocation = player.transform.localPosition;
    18.  
    19.         // Move forward our kicking power
    20.         targetLocation += player.transform.forward * currentKickingPower;
    21.  
    22.         // Set our location there
    23.         transform.localPosition = targetLocation;
    24.  
    25.     }
    26.     else{
    27.         sprite.enabled = false;
    28.         currentKickingPower = 0;
    29.     }
    30.  
    31. }
    32.  
     
    JakobRW likes this.
  6. JakobRW

    JakobRW

    Joined:
    Aug 7, 2016
    Posts:
    4
    Thank you for the detailed answer, this is more to take in than I imagined so I'll wait until tomorrow, when I'm not so tired. I'll let you know if I get it to work!
     
  7. ladyonthemoon

    ladyonthemoon

    Joined:
    Jun 29, 2015
    Posts:
    236
    Well, thanks for the precision; I apparently didn't understand and I understand less now. Not your fault, of course.
     
  8. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,738
    more or less multiply anything that happens in update by deltaTime, and instead of it doing what you told it to do over 1 frame update, it does it over 1 second.
    Translate(-4, 0, 0) would move you -4 units every Update, while Translate(-4f * Time.deltaTime, 0, 0) would move you -4 units every second.
     
    Bunny83 likes this.
  9. hawksprite

    hawksprite

    Joined:
    Dec 24, 2012
    Posts:
    11
    The easiest way to think of Delta time is in the scope of 1 Second real world time and the float value of 1.0f

    If you have a script that you want to run every frame and move a character 1 unit every second then you can utilize Time.deltaTime

    So for instance, if your script runs 30 times because the program is rendering at 30 FPS then you would want the value to be 1/30 each time the script ran. Because if you add 1/30 30 times it comes out to 1. However, if you actually set your value to 1/30 and the program actually runs at 60 FPS now you're going to have moved 2 units after a second has passed. So by multiplying TIme.deltaTime by 1.0f you get the mathematical equivalent of what the fraction of that value should be for the number of frames that will render until a second has passed.
     
    passerbycmc likes this.
  10. ladyonthemoon

    ladyonthemoon

    Joined:
    Jun 29, 2015
    Posts:
    236
    Okay. My first understanding of Time.deltaTime was "Time.deltaTime = 1 second". So -4 * Time.deltaTime would translate in current language into "-4 per second". How is that?
     
  11. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,738
    yes correct

    The value of time.deltaTime changes based on your framerate, it doesn't represent 1 second, it represents how long a frame takes to update and is equal to 1 divided by your framerate.

    If you are running at 60fps time.deltaTime is equal to 1/60, and 1/30 for 30fps etc.

    @hawksprite explained it well
     
    ladyonthemoon likes this.
  12. ladyonthemoon

    ladyonthemoon

    Joined:
    Jun 29, 2015
    Posts:
    236
    Ah, now I understand! Thank you! :)

    I had noticed that translations movement happened way too fast for my liking when set by script; so, now I use animations instead; they allow me to control the duration of the movement. ;)
     
  13. JakobRW

    JakobRW

    Joined:
    Aug 7, 2016
    Posts:
    4
    Well, I made it work! I just needed to change my approach a bit. Thank you so much for helping me out, without you I'd probably still think it was Time.deltaTime I was having trouble with.
     
    Thorlar and hawksprite like this.
  14. kingdom216

    kingdom216

    Joined:
    Apr 13, 2021
    Posts:
    45
    I am having a similar issue, when I don't use Time.deltaTime, my characters move freely, but when I put it on they walk and run in place while barely jumping. The following is from a tutorial on YouTube by IheartGameDev so please do not ask me why things are used the way they are. My main problem is trying to get the jump animation to work like the walking and running do. When I take off TdT the character lifts in the air but doesn't animate, so I put TdT back in the code to try and fix this, but like I said the character just runs and walks in place.

    Code (CShARP):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.InputSystem;
    6.  
    7. public class AnimationAndMovementController : MonoBehaviour
    8. {
    9.  
    10.     PlayerInput playerInput;
    11.     CharacterController characterController;
    12.     Animator animator;
    13.  
    14.  
    15.     int isWalkingHash;
    16.     int isRunningHash;
    17.  
    18.     Vector2 currentMovementInput;
    19.     Vector3 currentMovement;
    20.     Vector3 currentRunMovement;
    21.     bool isMovementPressed;
    22.     bool isRunPressed;
    23.  
    24.     float rotationFactorPerFrame = 15.0f;
    25.     float runMultiplier = 3.0f;
    26.     int zero = 0;
    27.     float gravity = -9.8f;
    28.     float groundedGravity = -.05f;
    29.  
    30.     bool isJumpPressed = false;
    31.     float initialJumpVelocity;
    32.     float maxJumpHeight = 4.0f;
    33.     float maxJumpTime = .75f;
    34.     bool isJumping = false;
    35.     int isJumpingHash;
    36.     bool isJumpAnimating = false;
    37.  
    38.     void Awake()
    39.     {
    40.         playerInput = new PlayerInput();
    41.         characterController = GetComponent<CharacterController>();
    42.         animator = GetComponent<Animator>();
    43.  
    44.         isWalkingHash = Animator.StringToHash("isWalking");
    45.         isRunningHash = Animator.StringToHash("isRunning");
    46.         isJumpingHash = Animator.StringToHash("isJumping");
    47.  
    48.         playerInput.CharacterControls.Move.started += onMovementInput;
    49.         playerInput.CharacterControls.Move.canceled += onMovementInput;
    50.         playerInput.CharacterControls.Move.performed += onMovementInput;
    51.         playerInput.CharacterControls.Run.started += onRun;
    52.         playerInput.CharacterControls.Run.canceled += onRun;
    53.         playerInput.CharacterControls.Jump.started += onJump;
    54.         playerInput.CharacterControls.Jump.canceled += onJump;
    55.  
    56.         setupJumpVariables();
    57.     }
    58.  
    59.     void setupJumpVariables()
    60.     {
    61.         float timeToApex = maxJumpTime / 2;
    62.         gravity = (-2 * maxJumpHeight) / Mathf.Pow(timeToApex, 2);
    63.         initialJumpVelocity = (2 * maxJumpHeight) / timeToApex;
    64.     }
    65.  
    66.     void handleJump()
    67.     {
    68.         if (!isJumping && characterController.isGrounded && isJumpPressed)
    69.         {
    70.             animator.SetBool("isJumpingHash", true);
    71.             isJumpAnimating = true;
    72.             isJumping = true;
    73.             currentMovement.y = initialJumpVelocity * 1.5f;
    74.             currentRunMovement.y = initialJumpVelocity * 1.5f;
    75.         }
    76.         else if (!isJumpPressed && isJumping && characterController.isGrounded)
    77.         {
    78.             isJumping = false;
    79.         }
    80.     }
    81.  
    82.     void onJump(InputAction.CallbackContext context)
    83.     {
    84.         isJumpPressed = context.ReadValueAsButton();
    85.         Debug.Log(isJumpPressed);
    86.     }
    87.  
    88.     void onRun(InputAction.CallbackContext context)
    89.     {
    90.         isRunPressed = context.ReadValueAsButton();
    91.     }
    92.  
    93.     void handleRotation()
    94.     {
    95.         Vector3 positionToLookAt;
    96.  
    97.         positionToLookAt.x = currentMovement.x;
    98.         positionToLookAt.y = 0.0f;
    99.         positionToLookAt.z = currentMovement.z;
    100.         Quaternion currentRotation = transform.rotation;
    101.  
    102.  
    103.  
    104.         if (isMovementPressed)
    105.         {
    106.             Quaternion targetRotation = Quaternion.LookRotation(positionToLookAt);
    107.             transform.rotation = Quaternion.Slerp(currentRotation, targetRotation, rotationFactorPerFrame);
    108.         }
    109.     }
    110.  
    111.     void onMovementInput(InputAction.CallbackContext context)
    112.     {
    113.         currentMovementInput = context.ReadValue<Vector2>();
    114.         currentMovement.x = currentMovementInput.x;
    115.         currentMovement.z = currentMovementInput.y;
    116.         currentRunMovement.x = currentMovementInput.x * runMultiplier;
    117.         currentRunMovement.z = currentMovementInput.y * runMultiplier;
    118.         isMovementPressed = currentMovementInput.x != 0 || currentMovementInput.y != 0;
    119.     }
    120.  
    121.     void handleAnimation()
    122.     {
    123.         bool isWalking = animator.GetBool(isWalkingHash);
    124.         bool isRunning = animator.GetBool(isRunningHash);
    125.  
    126.         if (isMovementPressed && !isWalking)
    127.         {
    128.             animator.SetBool(isWalkingHash, true);
    129.         }
    130.  
    131.         else if (!isMovementPressed && isWalking)
    132.         {
    133.             animator.SetBool(isWalkingHash, false);
    134.         }
    135.  
    136.         if ((isMovementPressed && isRunPressed) && !isRunning)
    137.         {
    138.             animator.SetBool(isRunningHash, true);
    139.         }
    140.  
    141.         else if ((!isMovementPressed || !isRunPressed) && isRunning)
    142.         {
    143.             animator.SetBool(isRunningHash, false);
    144.         }
    145.     }
    146.  
    147.     void handleGravity()
    148.     {
    149.         bool isFalling = currentMovement.y <= 0.0f || !isJumpPressed;
    150.         float fallMultiplier = 2.0f;
    151.  
    152.         if (characterController.isGrounded) {
    153.             if (isJumpAnimating) {
    154.                animator.SetBool("isJumpingHash", false);  
    155.                isJumpAnimating = false;
    156.             }
    157.             currentMovement.y = groundedGravity * Time.deltaTime;
    158.             currentRunMovement.y = groundedGravity * Time.deltaTime;
    159.         }else if (isFalling) {
    160.            float previousYVelocity = currentMovement.y;
    161.            float newYVelocity = currentMovement.y + (gravity * fallMultiplier * Time.deltaTime);
    162.            float nextYVelocity = (previousYVelocity + newYVelocity) * .5f;
    163.            currentMovement.y = nextYVelocity;
    164.            currentRunMovement.y = nextYVelocity;
    165.            
    166.        
    167.         } else {
    168.             float previousYVelocity = currentMovement.y;
    169.             float newYVelocity = currentMovement.y + (gravity);
    170.             float nextYVelocity = (previousYVelocity + newYVelocity) * .5f;
    171.             currentMovement.y = nextYVelocity;
    172.             currentRunMovement.y = nextYVelocity;
    173.         }
    174.     }
    175.  
    176.     // Update is called once per frame
    177.     void Update()
    178.     {
    179.         handleRotation();
    180.         handleAnimation();
    181.  
    182.         if (isRunPressed)
    183.         {
    184.             characterController.Move(currentRunMovement * Time.deltaTime);
    185.         }
    186.         else
    187.         {
    188.             characterController.Move(currentMovement * Time.deltaTime);
    189.         }
    190.         handleGravity();
    191.         handleJump();
    192.     }
    193.  
    194.     void OnEnable()
    195.     {
    196.         playerInput.CharacterControls.Enable();
    197.     }
    198.  
    199.     void OnDisable()
    200.     {
    201.         playerInput.CharacterControls.Disable();
    202.     }
    203. }
    204.  
     
  15. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,373
Thread Status:
Not open for further replies.