- Home /
Builds running at different speeds?
I'm working on a first-person platforming game.
After building to Windows and WebGl, I have found that my Unity project runs at a different speed on each build, as well as in the editor. My physics are coded, and I've tried both a regular as well as fixed update, but it still doesn't work right. Currently, the Windows build is running way faster than the editor. I haven't tried building to WebGl yet. Here is the main script that I use for movement/gravity for my player.
using UnityEngine;
using System.Collections;
public class SaucyMove : MonoBehaviour
{
// Moving fields
// This will make the variable below appear in the inspector
public float speed = 12.0f; // speed while grounded
public float maxSpeed = 1.5f;
public float runSpeed = 24.0f;
public float maxRunSpeed = 3.0f;
[SerializeField] private bool running = false;
public float airSpeed = 24.0f; // speed while airbound
public float jumpSpeed = 12.0f; // speed of jumps
public float gravity = 0.4f; // rate of gravity
public float augGravityMult = 1.0f;
public float groundFriction = 1.5f;
public bool airMovingEnabled = false;// can the object change velocity in air?
public bool easyAirMoving = true; // if airMoving enabled, is the air moving easy?
public bool easyMoving = false;
public bool wallJumpingEnabled = true;
public float wallMultiplier = 0.2F; // speed of gravity while on wall
public float wallJumpSpeed = 10.0F; // speed of jumps off walls
public bool airMoveDelayEnabled = true;
public float airMoveDelay = 3.0F;
private float currentAirMoveDelay = 0.0F;
public int jumpLimit = 1; // Number of consecutive jumps possible after touching ground or wall
private bool wallCollision = false; // is the object colliding with a wall?
private int jumpCounter = 0; // counts number of consecutive jumps since last touching ground or wall
private float currentWallMultiplier = 1.0F; // current gravity rate due to present/not present wall
private float currentAugGravity = 1.0F;
[SerializeField] Vector3 deltaVelocity = Vector3.zero; // direction of movement (x,y,z)
[SerializeField] Vector3 currentVelocity = Vector3.zero;
[SerializeField] Vector3 inputVelocity = Vector3.zero;
[SerializeField] Vector3 airVelocity = Vector3.zero;
[SerializeField] Vector3 wallCollisionNorm = Vector3.zero; // normal of wall collision (x,y,z)
[SerializeField] CharacterController player; // CharacterController component of the object is called "player"
[SerializeField] Vector3 lastPos = Vector3.zero;
void Start()
{
player = GetComponent<CharacterController>();
}
void Update()
{
if (!wallCollision)
{
currentWallMultiplier = 1.0F;
}
if (Input.GetButton("Run"))
{
running = true;
}
else
{
running = false;
}
if (airMoveDelayEnabled)
{
if (!(currentAirMoveDelay == 0f))
{
updateAirMoveDelay();
} else
{
airMovingEnabled = true;
}
}
if (player.isGrounded) // if grounded
{
deltaVelocity.y = 0;
currentVelocity.y = 0;// set the y change to 0
jumpCounter = 0;
airVelocity = Vector3.zero;
GroundMove(); // change deltaVelocity for object on ground
} else if (airMovingEnabled)
{
AirMove(); // change deltaVelocity for object in air
}
ApplyGravity(); // apply gravity
if (Input.GetButtonDown("Jump")) // if the jump button is pressed
{
Jump(); // jump
}
if (!Input.GetButton("Crouch"))
{
currentAugGravity = 1.0f;
} else
{
currentAugGravity = augGravityMult;
}
// change currentVelocity according to deltaVelocity
currentVelocity.y += deltaVelocity.y;
if (!player.isGrounded && airMovingEnabled)
{
if (easyAirMoving) // in the air, easyAirMoving
{
deltaVelocity.x = airVelocity.x;
deltaVelocity.z = airVelocity.z;
currentVelocity.x = deltaVelocity.x;
currentVelocity.z = deltaVelocity.z;
}
else // in the air, not easyAirMoving
{
currentVelocity.x += deltaVelocity.x;
currentVelocity.z += deltaVelocity.z;
currentVelocity.x += airVelocity.x;
currentVelocity.z += airVelocity.z;
}
} else
{
if (easyMoving) //on the ground, easy moving
{
currentVelocity.x = deltaVelocity.x;
currentVelocity.z = deltaVelocity.z; // change player's position according to currentVelocity
} else //on the ground, normal moving
{
currentVelocity.x += deltaVelocity.x;
currentVelocity.z += deltaVelocity.z;
}
}
player.Move(currentVelocity * Time.fixedDeltaTime);
ApplyFriction(); // apply friction
StaticPositionVelocity(); // if position doesn't change, currentVelocity is set to 0
MaxSpeedCap(); // stops speed from exceeding maxSpeed
lastPos = transform.position;
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
if (hit.normal.y < 0.1f && !player.isGrounded)
{
currentWallMultiplier = wallMultiplier;
jumpCounter = 0;
airVelocity = Vector3.zero;
wallCollision = true;
wallCollisionNorm = hit.normal;
Debug.DrawRay(hit.point, hit.normal, Color.red, 5F);
}
else
{
currentWallMultiplier = 1.0F;
wallCollision = false;
Debug.DrawRay(hit.point, hit.normal, Color.green, 10F);
}
}
/*custom functions
*
*
*
*
*/
private void GroundMove()
{
inputVelocity = new Vector3(Input.GetAxis("Horizontal"), deltaVelocity.y, Input.GetAxis("Vertical"));
deltaVelocity = transform.TransformDirection(inputVelocity);
if (running)
{
deltaVelocity.x *= runSpeed;
deltaVelocity.z *= runSpeed;
} else
{
deltaVelocity.x *= speed; // set the x change to speed
deltaVelocity.z *= speed; // set the z change to speed
}
// reset the jumpCounter
}
private void updateAirMoveDelay()
{
currentAirMoveDelay -= Time.fixedDeltaTime;
if(currentAirMoveDelay < 0)
{
currentAirMoveDelay = 0;
}
}
private void AirMove()
{
inputVelocity = new Vector3(Input.GetAxis("Horizontal"), airVelocity.y, Input.GetAxis("Vertical"));
airVelocity = transform.TransformDirection(inputVelocity);
airVelocity.x *= airSpeed;
airVelocity.z *= airSpeed;
airVelocity.y = 0;
}
private void ApplyGravity()
{
if (!wallCollision || (wallCollision && currentVelocity.y > 0))
{
deltaVelocity.y = -1 * gravity;
}
else
{
deltaVelocity.y = -1 * gravity * currentWallMultiplier;
}
deltaVelocity.y *= currentAugGravity;
Debug.Log(deltaVelocity.y);
}
private void Jump()
{
if (wallCollision) // if colliding with a wall
{
if (player.isGrounded) // if grounded
{
deltaVelocity.y = jumpSpeed; // set the y change to jumpSpeed
}
else if (wallJumpingEnabled)
{
deltaVelocity += wallCollisionNorm * wallJumpSpeed;
deltaVelocity.y = jumpSpeed;
wallCollision = false;
if (airMoveDelayEnabled)
{
airMovingEnabled = false;
currentAirMoveDelay = airMoveDelay;
}
}
}
else // if not colliding with a wall
{
if (player.isGrounded) // if grounded
{
deltaVelocity.y += jumpSpeed; // set the y change to jumpSpeed
}
if (!player.isGrounded && jumpCounter < (jumpLimit - 1)) // if the player is in the air, but their jumpCounter hasn't hit the limit
{
currentVelocity.y = 0;
deltaVelocity.y += jumpSpeed; // set the y change to jumpSpeed
jumpCounter++; // add a jump to the jumpCounter
}
}
}
private void StaticPositionVelocity()
{
if (transform.position.x == lastPos.x)
{
currentVelocity.x = 0;
deltaVelocity.x = 0;
}
if (transform.position.z == lastPos.z)
{
currentVelocity.z = 0;
deltaVelocity.z = 0;
}
if (transform.position.y == lastPos.y)
{
currentVelocity.y = 0;
deltaVelocity.y = 0;
}
}
private void MaxSpeedCap()
{
if (!running)
{
if (Mathf.Abs(currentVelocity.x) > maxSpeed)
{
if (currentVelocity.x > 0)
{
currentVelocity.x = maxSpeed;
}
else
{
currentVelocity.x = -maxSpeed;
}
}
if (Mathf.Abs(currentVelocity.z) > maxSpeed)
{
if (currentVelocity.z > 0)
{
currentVelocity.z = maxSpeed;
}
else
{
currentVelocity.z = -maxSpeed;
}
}
} else
{
if (Mathf.Abs(currentVelocity.x) > maxRunSpeed)
{
if (currentVelocity.x > 0)
{
currentVelocity.x = maxRunSpeed;
}
else
{
currentVelocity.x = -maxRunSpeed;
}
}
if (Mathf.Abs(currentVelocity.z) > maxRunSpeed)
{
if (currentVelocity.z > 0)
{
currentVelocity.z = maxRunSpeed;
}
else
{
currentVelocity.z = -maxRunSpeed;
}
}
}
}
private void ApplyFriction()
{
if (player.isGrounded)
{
//friction applied to x
if (deltaVelocity.x == 0)
{
if (currentVelocity.x > 0)
{
if (currentVelocity.x - groundFriction <= 0)
{
currentVelocity.x = 0;
}
else
{
currentVelocity.x -= groundFriction;
}
}
else
{
if (currentVelocity.x + groundFriction >= 0)
{
currentVelocity.x = 0;
}
else
{
currentVelocity.x += groundFriction;
}
}
}
//friction applied to z
if (deltaVelocity.z == 0)
{
if (currentVelocity.z > 0)
{
if (currentVelocity.z - groundFriction <= 0)
{
currentVelocity.z = 0;
}
else
{
currentVelocity.z -= groundFriction;
}
}
else
{
if (currentVelocity.z + groundFriction >= 0)
{
currentVelocity.z = 0;
}
else
{
currentVelocity.z += groundFriction;
}
}
}
}
}
}
Any help solving this problem would be appreciated. Thanks!
Answer by AaronXRDev · Nov 06, 2018 at 07:09 AM
A good practice to get into when manipulating variables in Update is to multiply them by Time.deltaTime. This will keep them running at a consistent rate across different framerates.
Here is the reference for Time.deltaTime
Here's an example:
private float xSpeed;
private float ySpeed;
void Update()
{
xSpeed += 2f * Time.deltaTime; // This will increase at the same speed whether the framerate is 30, 60, or 90
Debug.Log("x: " + xSpeed.ToString());
ySpeed += 2f; // This will increase by 60/s at 30fps, 120/s at 60fps, and 180/s at 90fps.
Debug.Log("y: " + ySpeed.ToString());
}
Your answer
Follow this Question
Related Questions
Does building game generate the lightmaps? 1 Answer
Distribute terrain in zones 3 Answers
Android app bundle(aab) build problem 2 Answers
ios build problem 1 Answer
Problems when making a build of a game for testing. 1 Answer