- Home /
Player is overjumping (jumping at least twice when it shouldn't)
Hi, I am at the moment coding the movement script for my player object, but I've encountered a problem where the player jumps like twice, making him jump really high, I think it's because I make the player jump if he is grounded and the left joystick goes above 0.8, so sometimes it inputs twice before leaving the ground, is there any workaround for that? here's my code:
using UnityEngine;
using System.Collections;
public class PlayerMovementScript : MonoBehaviour {
Rigidbody2D body2D;
Transform myTransform;
bool facingRight = true;
public Transform graphicsObject;
public Transform swordObject;
float direction;
public float walkVelocity;
public float lerpVelocity;
public float jumpVelocity;
bool isJumping;
void Start () {
body2D = GetComponent<Rigidbody2D>();
myTransform = GetComponent<Transform>();
}
bool isGrounded () {
RaycastHit2D[] hits = Physics2D.RaycastAll(transform.position, -Vector2.up, 1.05f);
foreach (RaycastHit2D hit in hits) {
if (hit.transform != myTransform) {
return true;
}
}
return false;
}
void Update () {
direction = Mathf.Lerp(direction,Input.GetAxis("HorizontalLeft"), lerpVelocity * Time.deltaTime);
direction = Mathf.Clamp(direction, -1f, 1f);
if (isGrounded()) {
if (Input.GetButtonDown("Jump") || Input.GetAxis("VerticalLeft") >= 0.8f) {
body2D.velocity += new Vector2(0f, jumpVelocity);
}
}
body2D.velocity = new Vector2(direction * walkVelocity, rigidbody2D.velocity.y);
if (swordObject.localRotation.z <= 0.7f && swordObject.localRotation.z >= -0.7f) {
graphicsObject.localScale = new Vector3 (1f, graphicsObject.localScale.y, graphicsObject.localScale.z);
}
else {
graphicsObject.localScale = new Vector3 (-1f, graphicsObject.localScale.y, graphicsObject.localScale.z);
}
}
void OnGUI () {
GUILayout.Label(facingRight.ToString() + " " + swordObject.localRotation.z.ToString("F2") + " isGrounded " + isGrounded());
}
}
Thanks in advance, btw, the inputs are set for gamepads, that's the reason why I want to use left joystick to jump and give the option to also use a button.
Answer by Kiwasi · Jul 25, 2014 at 01:42 PM
This problem is due to doing physics work in update. There are plenty of other questions with more sophisticated answers. In short get your input in Update and apply any changes to the rigidbody in fixed update.
Yeah I was thinking about that, but a friend of $$anonymous$$e once told me that since I'm directly changing the velocity it wouldn't need to be on FixedUpdate, is he wrong?
edit: that seems to work perfectly, since I'm only in the prototyping stage yet and there isn't much to the game yet, I feel like I should rewrite the scripts, they're quite a mess and not so flexibe for the future.
The reason this answer works is that Update and FixedUpdate run at different speeds. If you were setting velocity you would be fine (but still bad practice), however you are adding to velocity. This is essentially the same as AddForce.
Here is the steps showing why this works
User presses jump key
Update runs. User is grounded, velocity increases.
Update runs. User is grounded, velocity increases.
FixedUpdate runs. User moves. User is no longer grounded.
Funny I added velocity, didn't even remember, I usually set it directly ;p
Answer by stevethorne · Jul 25, 2014 at 01:37 PM
You're going to need to track the vertical of the left analog stick to create something similar to GetButtonDown. This can easily be done by saving the last frames VerticalLeft information and then doing something like:
if ( Input.GetButtonDown( "Jump" ) || ( Input.GetAxis( "VerticalLeft" ) >= 0.8f && lastVerticalLeft < 0.8f ) )
Then the next frame the lastVerticalLeft will be greater than or equal to 0.8f and the if statement will fail.
How would I change keep the last frame value? I suppose I would use something like yield waitTilEndOfFrame thingy? I'll try Bored $$anonymous$$oron's answer though
Just set a variable called lastVerticalLeft to Input.GetAxis( "VerticalLeft" ) at the end of the frame, and then use it in the if statement.
some pseudo code
void Update()
{
vertical = Input.GetAxis( "VerticalLeft" );
if ( jump || ( vertical >= 0.8f && lastvertical < 0.8f ) )
do things
lastvertical = vertical
}
Your answer
Follow this Question
Related Questions
jump and check ground problem! 2 Answers
Jumping By Set Amount Instead of By Speed 1 Answer
GameObject starts drifting on X axis when doing high jump 0 Answers
Raycast2D Only returns true 1 Answer