Hi.
I wrote 2d jumping script without physics, but it’s not good working. mean, after press Space key at the first time, jumping is longer than second pressed space key. where is the problem?
Is this code correct for non-physics jumping?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Player Parameter
struct PlayerParam
{
public float x;
public float y;
}
public class PlayerController : MonoBehaviour
{
PlayerParam player = new PlayerParam();
[SerializeField] private bool isGrounded = false;
private float jumpSpeed = 300f;
private float gravity = 9.81f;
void Update()
{
player.x = transform.position.x;
player.y = transform.position.y;
IsGroundedRaycast();
Jumping();
transform.position = new Vector2(player.x, player.y);
}
// Check the player is on the ground
private bool IsGroundedRaycast()
{
isGrounded = Physics2D.Linecast(transform.position, transform.position + -transform.up, 1 << LayerMask.NameToLayer("Ground"));
Debug.DrawLine(transform.position, transform.position + -transform.up, Color.red);
return isGrounded;
}
// Jumping
private void Jumping()
{
if (isGrounded)
{
player.y = 0;
if (Input.GetKeyDown(KeyCode.Space))
{
player.y = jumpSpeed * Time.deltaTime;
}
}
else
{
player.y -= gravity * Time.deltaTime;
}
}
}
Well, you’re multiplying your jumpSpeed by Time.deltaTime, which is the time in-between frames. That means your jumpSpeed is going to be dependent on your framerate.
without multiplying my jumpSpeed by Time.deltaTime, I have another problem. after press space key, player.y set to jumpSpeed very fast. or in other words, player start falling from jumpSpeed position.
You seem to be confusing integrating motion with adding forces.
This is integrating motion i.e. you’re modifying the Y by gravity/sec.
This just sets the Y position to a fixed amount. It’s only “jumping” if you mean instantly move to a position Y then fall back gradually using the motion you define with gravity.
Honestly, I have no idea why you don’t just use a Kinematic Rigidbody2D here and just manipulate its velocity. You can add your JumpSpeed to the velocity and it’ll move upwards and then continually add the downwards force of your gravity.
If not then you need a “float PlayerVerticalSpeed”. You then add your jump-speed to it AND the gravity to it. Then each update you add the PlayerVerticalSpeed * Time.deltaTime to your Player.y. In other words, you need to add vertical velocity then integrate that into position changes.
The whole point of a Rigidbody2D is to drive the Transform on your behalf; never ever set it as it completely defeats the purpose of it. Use the Rigidbody2D API to check position instead of the “Player” thing.
Also note that if your game suits it, just run physics per-frame then you don’t need to mess with FixedUpdate.
Also, I feel compelled to show you a much simpler (1 line) method to detect if you’re in contact:
I mean, don’t modify the Transform, let the Rigidbody2D do that which happens when the simulation runs and the bodies have moved. I’m not telling you which specific call to use because that depends on what you’re doing. There’s MovePosition/MoveRotation/position/rotation/velocity/AddForce etc on the Rigidbody2D.
If you change the physics to run per-frame in “Project Settings > Physics 2D > Simulation Mode > Update” then the simulation runs after the “Update” callback per-frame and not after the “FixedUpdate” callback per fixed-update (not per-frame) so that means you can do your work in the"Update" callback, yes.