Hey, I'm trying to build a raycast based character controller and I can't make the Jump method framerate independent no matter what I try, here is a test project from one of the tutorials I've been following, which is also not framerate independent. Just press play, move with arrows or wasd and jump with spacebar, and try to clear the pillar. Now change the public variable "Target Framerate" on the Player script from 30 to 60+ and try again. Why is the jump affected by the framerate in this scenario? Thanks
It's better to post your code rather than requiring a download. I noticed this line in the player: velocity.y += gravity * Time.deltaTime; A compiler will do multiplication before addition, so I think you want: (velocity.y += gravity) * Time.deltaTime; I didn't try it or anything.
Ditto on the posting of the relevant code, not a whole project. Anyway, so that others can assist, here's that code of yours: Code (CSharp): public class Player : MonoBehaviour { public int targetFramerate = 30; public float moveSpeed = 6; public float jumpVelocity = 6; public float gravity = -25; Vector3 velocity; Controller2D controller; void Start() { controller = GetComponent<Controller2D> (); } void Update() { Application.targetFrameRate = targetFramerate; if (controller.collisions.above || controller.collisions.below) velocity.y = 0; Vector2 input = new Vector2 (Input.GetAxisRaw ("Horizontal"), Input.GetAxisRaw ("Vertical")); //JUMP if (Input.GetKeyDown (KeyCode.Space) && controller.collisions.below) velocity.y = jumpVelocity; //GRAVITY velocity.y += gravity * Time.deltaTime; //MOVE velocity.x = input.x * moveSpeed; controller.Move (velocity * Time.deltaTime); } } Some reactions: It looks like you're applying gravity even when grounded. Maybe you shouldn't be doing that? As for the framerate issue, my hunch is that it's because you're multiplying by Time.deltaTime twice. I'd need to do some math on that to verify it, but it seems weird. You're reducing the velocity by a deltaTime-based amount, and then moving a deltaTime-based amount. Perhaps its compounding the time in a weird way. Maybe it should be like this? Code (CSharp): //JUMP if (Input.GetKeyDown (KeyCode.Space) && controller.collisions.below) velocity.y = jumpVelocity; //MOVE velocity.x = input.x * moveSpeed; velocity *= Time.deltaTime; //GRAVITY velocity.y += gravity * Time.deltaTime; controller.Move (velocity);
I've figured out why this is happening thanks to Eno-Khaon on Unity Answers It's easier to understand by looking at it visually so I suggest taking a look at what he posted, basically the more frames, the smaller the subtracted amount will be (because it's multiplied every frame by delta) so the higher it will jump. I'll keep looking for a solution @dgoyette thanks for posting the code
So Bunny31's solution at my Unity Answers post works perfectly, the gravity has to be applied in two parts, example: Code (CSharp): //GRAVITY velocity.y += gravity * 0.5f * Time.deltaTime; //MOVE velocity.x = input.x * moveSpeed; controller.Move (velocity * Time.deltaTime); //GRAVITY velocity.y += gravity * 0.5f * Time.deltaTime;