Reputation: 1
I'm trying to port my friend's Scratch game to Unity for fun, but the code for deceleration is causing the player to speed up and slow down depending on the framerate. The maximum X velocity should be 6.75, which it is at 30 fps, (scratch's usual framerate), but when the FPS changes his speed varies up to ~7.5. Code (Unfinished):
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public Vector2 Velocity, WallJumpForce;
public float Acceleration, Decceleration;
public float Gravity, JumpForce;
public int TargetFPS;
void Update()
{
Velocity.y -= Gravity;
if(Input.GetKey("right") || Input.GetKey("d"))
Velocity.x += Acceleration * SDT();
if(Input.GetKey("left") || Input.GetKey("a"))
Velocity.x -= Acceleration * SDT();
Velocity.x -= Velocity.x*(1-Decceleration) * SDT();
Move(Velocity.x, 0);
Debug.Log(1 / Time.deltaTime + ", " + SDT());
Application.targetFrameRate = TargetFPS;
}
void Move(float x, float y) //Converts Scratch Units to Unity Units
{
transform.position += new Vector3(x, y, 0) * 1.2f * Time.deltaTime;
}
float SDT() //Basically allows Scratch variables designed for 30fps work in unity
{
return 30 * Time.deltaTime;
}
}
I've discovered that changing Velocity.x *= Decceleration * SDT();
to
Velocity.x -= Velocity.x*(1-Decceleration) * SDT();
helps, but does not fix the problem.
For reference, this is the game I'm porting.
https://scratch.mit.edu/projects/590825095
Upvotes: 0
Views: 1051
Reputation: 1
A few years late but just in case anybody stumbles upon this. You should be using FixedUpdate() for movement. I believe fixed update runs seveal times per frame in some cases and is designed to run at fixed intervals for this exact reason.
Upvotes: 0
Reputation: 3291
Do yourself a favor and verify your units every single time you write a physics equation. In this case verifying your units will solve the problem.
Velocity has units of distance/time and gravity has units of distance/(time^2).
So lets examine the units on this line:
Velocity.y -= Gravity;
You are saying distance/time -= distance/(time^2).
Those units don't work!
Clearly you will have to multiply Gravity
by some amount of time to get a change in velocity. For that we have Δt, the amount of time that has passed since the last frame:
Velocity.y -= Gravity * Time.deltaTime;
Now the units are distance/time -= distance/(time^2)*time. That makes a whole lot more sense. Do that for all your physics equations and your problem will be solved.
Upvotes: 3