Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Resolved Game runs in slow motion in build compared to editor.

Discussion in 'Getting Started' started by MyNameIsMvn, Nov 8, 2021.

  1. MyNameIsMvn

    MyNameIsMvn

    Joined:
    Jun 20, 2021
    Posts:
    5
    Yep, it's the classic "why is it slower in the build" problem.

    This one I just can't solve. I'm pretty sure I got everything with the Time.deltaTime modifier. I've added a Text component to debug the timestep and the movement vector in-build and in-editor, and the values are the same in both. I am genuinely lost. Help is appreciated.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class PlayerMovement : MonoBehaviour
    7. {
    8.     Rigidbody2D rb;
    9.     SpriteRenderer sprite;
    10.     Vector2 movement = new Vector2(0, 0);
    11.     bool jump;
    12.     float velocity = 0f;
    13.     bool double_jump = false;
    14.     //public vars
    15.     public float gravity_mod = 1f;
    16.     public float jump_height = 2f;
    17.     public float speed_mod = 10f;
    18.     Text txt; //placeholder
    19.     // Start is called before the first frame update
    20.     void Start()
    21.     {
    22.         rb = GetComponent<Rigidbody2D>();
    23.         sprite = GetComponent<SpriteRenderer>();
    24.         txt = GameObject.Find("Placeholder").GetComponent<Text>();
    25.     }
    26.  
    27.     // Update is called once per frame
    28.     void Update()
    29.     {
    30.         //ROTATION SCRIPT. DO NOT USE FOR PLAYER, USE FOR OTHER STUFF
    31.         //Vector2 world_to_mouse = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    32.         //Vector2 direction = (world_to_mouse - (Vector2)transform.position).normalized;
    33.         //transform.up = direction;
    34.      
    35.         //ground detection
    36.         RaycastHit2D ground = Physics2D.CircleCast(transform.position, 0.4f, Vector2.down, 0.62f, LayerMask.GetMask("Ground"));
    37.  
    38.         //movement
    39.         movement.y = 0f;
    40.         Debug.DrawRay(transform.position, Vector2.down, Color.green);
    41.         if(ground.collider != null) {
    42.             movement.x = Input.GetAxisRaw("Horizontal");
    43.  
    44.         } else {
    45.             movement.x += Input.GetAxisRaw("Horizontal") * Time.deltaTime * 5;
    46.             movement.x = Mathf.Clamp(movement.x, -1f, 1f);
    47.             if(Input.GetAxisRaw("Horizontal") == 0) {
    48.                 if(movement.x > 0) {
    49.                     movement.x -= Time.deltaTime * 3;
    50.                 } else if(movement.x < 0) {
    51.                     movement.x += Time.deltaTime * 3;
    52.                 }
    53.             }
    54.         }
    55.         if(movement.x != 0) {
    56.             Debug.Log("Moving");
    57.         }
    58.         //jump
    59.         if(Input.GetButtonDown("Jump")) {
    60.             if(ground.collider != null) {
    61.                 jump = true;
    62.                 Debug.Log("JUMP YOU HECKER JUMP");
    63.             } else if(double_jump) {
    64.                 jump = true;
    65.                 double_jump = false;
    66.                 Debug.Log("Double jumping breaks the laws of physics.");
    67.             }
    68.         }
    69.         //ceiling detection
    70.         RaycastHit2D ceiling = Physics2D.CircleCast(transform.position, 0.4f, Vector2.up, 0.62f, LayerMask.GetMask("Ground"));
    71.         if(ceiling.collider != null) {
    72.             velocity = 0f;
    73.         }
    74.         //flip sprite depending on move direction
    75.         if(Input.GetAxisRaw("Horizontal") > 0) {
    76.             sprite.flipX = true;
    77.         } else if(Input.GetAxisRaw("Horizontal") < 0) {
    78.             sprite.flipX = false;
    79.         }
    80.     }
    81.  
    82.     void FixedUpdate() {
    83.         //gravity
    84.         RaycastHit2D ground = Physics2D.CircleCast(transform.position, 0.4f, Vector2.down, 0.62f, LayerMask.GetMask("Ground"));
    85.         if(ground.collider == null) {
    86.             velocity -= gravity_mod * Time.fixedDeltaTime;
    87.         } else {
    88.             Debug.Log("On ground");
    89.             velocity = 0f;
    90.             double_jump = true;
    91.         }
    92.         //jumping
    93.         if(jump == true) {
    94.             velocity = jump_height;
    95.             jump = false;
    96.         }
    97.         //movement
    98.         movement.y += velocity * Time.fixedDeltaTime * 100;
    99.         txt.text = new Vector3(movement.x * speed_mod, movement.y, 0).ToString(); //debugging movement vector
    100.         rb.MovePosition((Vector2)transform.position + new Vector2(movement.x * speed_mod, movement.y));
    101.     }
    102. }
    EDIT: Solution can be found here: https://forum.unity.com/threads/gam...uild-compared-to-editor.1194991/#post-7643443
     
    Last edited: Nov 10, 2021
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,588
    You're posting a large chunk of code but you're not really explaining the difference between the expected and actual.

    Why are you scaling this thing by the elapsed frame time here during the frame update?
    Code (CSharp):
    1. movement.x += Input.GetAxisRaw("Horizontal") * Time.deltaTime * 5;
    You don't use this per-frame, you use it per fixed-update and then scale it again by the fixed-update delta:
    Code (CSharp):
    1. movement.y += velocity * Time.fixedDeltaTime * 100;
    I believe you're trying to maintain some kind of acceleration here with movement then you integrate it into a velocity change but I'm not sure this is what you want and it's not necessarily the best way to achieve it.

    You're also doing physics queries per-frame which physics doesn't change (by default) per-frame and only during fixed-update (by default) so you're repeating work per-frame when it isn't changing.

    You are free to run physics per-frame if you want (see Project Settings > 2D Physics > Simulation Mode). If not thought, then only read the per-frame input during "Update" and then perform queries and logic during the fixed-update.

    If the frame-rate is 200 fps then you'll get 4 frame renders every 50hz fixed-update so you're running the logic again and again per-frame without any action of the physics system.
     
    Joe-Censored likes this.
  3. MyNameIsMvn

    MyNameIsMvn

    Joined:
    Jun 20, 2021
    Posts:
    5
    Apologies, I should be more specific.

    My player moves the speed I want it to move in the editor, but it moves slower when I build and run the game. This extends to both walking left/right and jumping, as if the game was running in slow-motion (hence the title of the thread). I'll see if I can send a recording when I'm back home to demonstrate what I mean.
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,588
    Yes, I read that from the title and it's not hard to understand. Not sure a video will help.

    I think I said everything I can say above in detail so you should refer to that.
     
    Joe-Censored likes this.
  5. MyNameIsMvn

    MyNameIsMvn

    Joined:
    Jun 20, 2021
    Posts:
    5
    Sorry, I thought I needed to provide clarification when you said I wasn't explaining the difference between expected and result.

    Alright, so you'd be right about the acceleration change for movement. It's meant to be a sort of air drift and I'm aware I could probably use rb.AddForce or similar, but honestly I just like manually making air-drift/gravity for some reason.

    So what you are saying is to only get input during Update(), and move all logic to FixedUpdate()? Sorry if I come off as lost, because frankly I am and I'm still in the process of learning.
     
  6. MyNameIsMvn

    MyNameIsMvn

    Joined:
    Jun 20, 2021
    Posts:
    5
    For debugging purposes, I decided to comment out the original rb.MovePosition (to disable normal movement) and add a new one underneath, which literally only moves the player to the right by
    5 * Time.fixedDeltaTime
    . It's placed at the bottom of FixedUpdate, and the entire line is literally just:
    Code (CSharp):
    1. rb.MovePosition((Vector2)rb.position + new Vector2(Time.fixedDeltaTime * 5, 0));
    And it's all that's dictating the player movement. It should be filtering out all the other logic, and just moving the player by a constant rate to the right.

    It is still moving slower in the build compared to the editor.

    Now, I just don't know anymore.
     
  7. MyNameIsMvn

    MyNameIsMvn

    Joined:
    Jun 20, 2021
    Posts:
    5
    I have found the issue! Or at least, part of it.

    Turning off VSync makes my game run normally in the build. I'm not sure if this is the root problem though, so I will be investigating further. Since all VSync does is limit the FPS, I must be missing something with the framerate dependency somehow...

    UPDATE: Found it! Messing with your timestep apparently messes up VSync, which in turn messes up your build's speed. I had my timestep set to 0.01 instead of 0.02. Setting it back to the latter solved the issue.
     
    Last edited: Nov 10, 2021
    NoMercy123, Lypheus and Hummy91 like this.