- Home /
How do i stop infinite Jumping in the air
Here is my Jump script: public class Jump : MonoBehaviour {
[Range(1, 10)]
public float jumpVelocity;
void Update () {
if (Input.GetButtonDown("Jump"))
{
GetComponent<Rigidbody2D>().velocity = Vector2.up * jumpVelocity; }
}
} and here is another script that i use to make the jump feel better: public class BetterJump : MonoBehaviour {
public float fallMultiplier = 2.5f;
public float lowJumpMultiplier = 2f;
Rigidbody2D rb;
void Awake()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
if (rb.velocity.y < 0)
{
rb.velocity += Vector2.up * Physics2D.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
} else if (rb.velocity.y > 0 && !Input.GetButton("Jump"))
{
rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - 1) * Time.deltaTime;
}
}
}
And here is a script that i am using to try and stop jumping mid air, but it is not working and i don't know why or how to fix it. :
public class Jump_Halt : MonoBehaviour { public KeyCode Jump; public string midjump = "f"; [Range(1, 10)] public float jumpVelocity;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if ((Input.GetButtonDown("Jump")) && (midjump == "f"))
{
GetComponent<Rigidbody2D> ().velocity = new Vector2(0, 5);
midjump = "t";
if (midjump == "t")
{
jumpVelocity = 0;
}
}
if (GetComponent<Rigidbody2D>().velocity.y == 0)
midjump = "f";
}
}
Any help would be appreciated, thanks.
Does your player can do 2 step jump? (I mean like some ninja games, the player can jump one more time while suspending in air)
Answer by KittenSnipes · Sep 27, 2018 at 02:17 AM
@Lizarlfos So I tend to use these two scripts quite often so maybe they can help you and you can further expand them. I explain a bit of the script through comments but I am lazy lol.
First Script: You can think of this script as the forces to apply to all types of movement
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Forces : MonoBehaviour {
//The height the object must be from the object beneath it
public float minGroundNormalY = .65f;
//Amount of gravity that acts on the object
public float gravityModifier = 1f;
//Variables
protected Vector2 targetVelocity;
protected bool grounded;
protected Vector2 groundNormal;
protected Rigidbody2D rb2d;
protected Vector2 velocity;
protected ContactFilter2D contactFilter;
protected RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
protected List<RaycastHit2D> hitBufferList = new List<RaycastHit2D>(16);
protected const float minMoveDistance = 0.001f;
protected const float shellRadius = 0.01f;
void OnEnable()
{
//Get the reference for our rigidbody
rb2d = GetComponent<Rigidbody2D>();
}
void Start()
{
//This is used to filter our results of contact
contactFilter.useTriggers = false;
//This sets the contact filter to filter the results that only include Collider2D on the layers defined by the layer mask.
//The layer mask in this case is: gameObject.layer
contactFilter.SetLayerMask(Physics2D.GetLayerCollisionMask(gameObject.layer));
//After all the filtering is setup. This sets the contact filter to filter results by the layer mask.
contactFilter.useLayerMask = true;
}
void Update()
{
targetVelocity = Vector2.zero;
ComputeVelocity();
}
//This is not a mistake. It is meant to be empty.
//This is defined in the class that actually defines
//the movement of the object.
protected virtual void ComputeVelocity()
{
}
//Set up our forces
void FixedUpdate()
{
velocity += gravityModifier * Physics2D.gravity * Time.deltaTime;
velocity.x = targetVelocity.x;
grounded = false;
Vector2 deltaPosition = velocity * Time.deltaTime;
Vector2 moveAlongGround = new Vector2(groundNormal.y, -groundNormal.x);
Vector2 move = moveAlongGround * deltaPosition.x;
Movement(move, false);
move = Vector2.up * deltaPosition.y;
Movement(move, true);
}
//Apply that good movement stuff
void Movement(Vector2 move, bool yMovement)
{
float distance = move.magnitude;
if (distance > minMoveDistance)
{
int count = rb2d.Cast(move, contactFilter, hitBuffer, distance + shellRadius);
hitBufferList.Clear();
for (int i = 0; i < count; i++)
{
hitBufferList.Add(hitBuffer[i]);
}
for (int i = 0; i < hitBufferList.Count; i++)
{
Vector2 currentNormal = hitBufferList[i].normal;
if (currentNormal.y > minGroundNormalY)
{
grounded = true;
if (yMovement)
{
groundNormal = currentNormal;
currentNormal.x = 0;
}
}
float projection = Vector2.Dot(velocity, currentNormal);
if (projection < 0)
{
velocity = velocity - projection * currentNormal;
}
float modifiedDistance = hitBufferList[i].distance - shellRadius;
distance = modifiedDistance < distance ? modifiedDistance : distance;
}
}
rb2d.position = rb2d.position + move.normalized * distance;
}
}
Second Script: The actual movement script where we define all of the movement
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//This class is defined by the previous class called Forces
public class PlayerMove : Forces
{
public float maxSpeed = 7;
public float jumpTakeOffSpeed = 7;
private SpriteRenderer spriteRenderer;
private Animator animator;
// Use this for initialization
void Awake()
{
spriteRenderer = GetComponent<SpriteRenderer>();
animator = GetComponent<Animator>();
}
//Gotta override this because we are defining it
protected override void ComputeVelocity()
{
Vector2 move = Vector2.zero;
move.x = Input.GetAxis("Horizontal");
if (Input.GetButtonDown("Jump") && grounded)
{
velocity.y = jumpTakeOffSpeed;
}
else if (Input.GetButtonUp("Jump"))
{
if (velocity.y > 0)
{
velocity.y = velocity.y * 0.5f;
}
}
//This statement is a nice way of doing a if/else statement to define the variable
bool flipSprite = (spriteRenderer.flipX ? (move.x > 0.01f) : (move.x < 0.01f));
if (flipSprite)
{
spriteRenderer.flipX = !spriteRenderer.flipX;
}
if (animator != null)
{
animator.SetBool("isGrounded", grounded);
animator.SetFloat("VelocityX", Mathf.Abs(velocity.x) / maxSpeed);
}
targetVelocity = move * maxSpeed;
}
}
Cheers for the response, i really appreciate it. However when i tried implementing the "Second Script: The actual movement script where we define all of the movement", i received multiple errors stating that "the name 'grounded' does not exist in this current context", or "the name 'velocity' does not exist in this current context, or "the name 'targetVelocity' does not exist in this current context, or "'$$anonymous$$ovement_forces.computeVelocity()':No suitable method found to overide".
Sorry if this seems like an obvious answer or a stupid question, I'm extremely new to c# coding. Cheers in advance.
If you want to catch my attention try doing @ and then my user name to notify me because I usually have my email up to notify me if a question has changed. Are your scripts similar to $$anonymous$$e but named differently? Or did you copy every bit?
I am going to try my best to explain the most likely reason your class is not working. First off your movement class is named different from $$anonymous$$e. If you know how to edit that should be no problem but you probably missed some important lines.
Instructions:
1) First, the class that deals with forces must be in a separate script. You can name it whatever you want. Example: public class Forces : $$anonymous$$onobehaviour
2) Second, the movement class must inherit (Think of it as this class is getting some genes from its parent) from the forces class so it can define them. Example: public class $$anonymous$$ovement_forces: Forces
Now for some explanation. The class that deals with forces is the parent in which the class that deals with movement inherits from. Basically it takes parts of the forces script and adds it to its own parts. We use these parts to help us deal with all of the forces and to tell if our character is grounded.
Override: We use this keyword to make changes to an already existing function that we inherited. Then we redefine it. Parent script does not define the ComputeVelocity function because only inherited scripts can define it.
If you want more help you can just post your entire script and I can make the proper edits.
Cheers :D
@$$anonymous$$ittenSnipes
Thankyou so much it all works now. You've been really helpful cheers :D
Your answer
Follow this Question
Related Questions
Distribute terrain in zones 3 Answers
Unity|C#| Card Game: How to draw a card for each 0.5 secs? 2 Answers
Character can jump mid air forever 3 Answers
Can someone help me with the jumping in this Player Controller script? 1 Answer
Rooms are infinitely spawning, don't know what's keeping the loop from ending 1 Answer