Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by CrazyPenguin · Mar 30, 2014 at 01:24 AM · c#physicsjumpdoublejump

Adding double jump to physics platformer kit?

Hi Guys

Have been trying to figure this out for a long time, I can get my player to double jump however if I keep pressing space he keeps jumping forever I understand why this is happening however I want to have him only jump twice. I Have the following.

 if (Input.GetButtonDown ("Jump") && !grounded)

                     Jump (dbljump);

Which is great, but how do i stop him being able to jump forever?

Here is the entire code: Would greatly appreciate your help.

 using UnityEngine;
 using System.Collections;
 
 //handles player movement, utilising the CharacterMotor class
 [RequireComponent(typeof(CharacterMotor))]
 [RequireComponent(typeof(DealDamage))]
 [RequireComponent(typeof(AudioSource))]
 public class PlayerMove : MonoBehaviour 
 {
     //setup
     public Transform mainCam, floorChecks;        //main camera, and floorChecks object. FloorChecks are raycasted down from to check the player is grounded.
     public Animator animator;                    //object with animation controller on, which you want to animate
     public AudioClip jumpSound;                    //play when jumping
     public AudioClip landSound;                    //play when landing on ground
     
     //movement
     public float accel = 70f;                    //acceleration/deceleration in air or on the ground
     public float airAccel = 18f;            
     public float decel = 7.6f;
     public float airDecel = 1.1f;
     [Range(0f, 5f)]
     public float rotateSpeed = 0.7f, airRotateSpeed = 0.4f;    //how fast to rotate on the ground, how fast to rotate in the air
     public float maxSpeed = 9;                                //maximum speed of movement in X/Z axis
     public float slopeLimit = 40, slideAmount = 35;            //maximum angle of slopes you can walk on, how fast to slide down slopes you can't
     public float movingPlatformFriction = 7.7f;                //you'll need to tweak this to get the player to stay on moving platforms properly
     
     //jumping
     public Vector3 jumpForce =  new Vector3(0, 13, 0);    //normal jump force
     public Vector3 dbljump =  new Vector3(0, 13, 90);    //normal jump force
     public Vector3 secondJumpForce = new Vector3(0, 13, 0); //the force of a 2nd consecutive jump
     public Vector3 thirdJumpForce = new Vector3(0, 13, 0);    //the force of a 3rd consecutive jump
     public float jumpDelay = 0.1f;                            //how fast you need to jump after hitting the ground, to do the next type of jump
     public float jumpLeniancy = 0.17f;                        //how early before hitting the ground you can press jump, and still have it work
     [HideInInspector]
     public int onEnemyBounce;                    
     
     private int onJump;
     private bool grounded;
     private Transform[] floorCheckers;
     private Quaternion screenMovementSpace;
     private float airPressTime, groundedCount, curAccel, curDecel, curRotateSpeed, slope;
     private Vector3 direction, moveDirection, screenMovementForward, screenMovementRight, movingObjSpeed;
     
     private CharacterMotor characterMotor;
     private EnemyAI enemyAI;
     private DealDamage dealDamage;
     
 
 
 
 
 
     //setup
     void Awake()
     {
         //create single floorcheck in centre of object, if none are assigned
         if(!floorChecks)
         {
             floorChecks = new GameObject().transform;
             floorChecks.name = "FloorChecks";
             floorChecks.parent = transform;
             floorChecks.position = transform.position;
             GameObject check = new GameObject();
             check.name = "Check1";
             check.transform.parent = floorChecks;
             check.transform.position = transform.position;
             Debug.LogWarning("No 'floorChecks' assigned to PlayerMove script, so a single floorcheck has been created", floorChecks);
         }
         //assign player tag if not already
         if(tag != "Player")
         {
             tag = "Player";
             Debug.LogWarning ("PlayerMove script assigned to object without the tag 'Player', tag has been assigned automatically", transform);
         }
         
         //usual setup
         mainCam = GameObject.FindGameObjectWithTag("MainCamera").transform;
         dealDamage = GetComponent<DealDamage>();
         characterMotor = GetComponent<CharacterMotor>();
         //gets child objects of floorcheckers, and puts them in an array
         //later these are used to raycast downward and see if we are on the ground
         floorCheckers = new Transform[floorChecks.childCount];
         for (int i=0; i < floorCheckers.Length; i++)
             floorCheckers[i] = floorChecks.GetChild(i);
     }
     
     //get state of player, values and input
     void Update()
     {    
         //handle jumping
         JumpCalculations ();
         //adjust movement values if we're in the air or on the ground
         curAccel = (grounded) ? accel : airAccel;
         curDecel = (grounded) ? decel : airDecel;
         curRotateSpeed = (grounded) ? rotateSpeed : airRotateSpeed;
                 
         //get movement axis relative to camera
         screenMovementSpace = Quaternion.Euler (0, mainCam.eulerAngles.y, 0);
         screenMovementForward = screenMovementSpace * Vector3.forward;
         screenMovementRight = screenMovementSpace * Vector3.right;
         
         //get movement input, set direction to move in
         float h = Input.GetAxisRaw ("Horizontal");
         float v = Input.GetAxisRaw ("Vertical");
         direction = (screenMovementForward * v) + (screenMovementRight * h);
         moveDirection = transform.position + direction;
         
 
     }
     
     //apply correct player movement (fixedUpdate for physics calculations)
     void FixedUpdate() 
     {
         //are we grounded
         grounded = IsGrounded ();
         //move, rotate, manage speed
         characterMotor.MoveTo (moveDirection, curAccel, 0.7f, true);
         if (rotateSpeed != 0 && direction.magnitude != 0)
             characterMotor.RotateToDirection (moveDirection , curRotateSpeed * 5, true);
         characterMotor.ManageSpeed (curDecel, maxSpeed + movingObjSpeed.magnitude, true);
         //set animation values
         if(animator)
         {
             animator.SetFloat("DistanceToTarget", characterMotor.DistanceToTarget);
             animator.SetBool("Grounded", grounded);
             animator.SetFloat("YVelocity", rigidbody.velocity.y);
         }
     }
     
     //prevents rigidbody from sliding down slight slopes (read notes in characterMotor class for more info on friction)
     void OnCollisionStay(Collision other)
     {
         //only stop movement on slight slopes if we aren't being touched by anything else
         if (other.collider.tag != "Untagged" || grounded == false)
             return;
         //if no movement should be happening, stop player moving in Z/X axis
         if(direction.magnitude == 0 && slope < slopeLimit && rigidbody.velocity.magnitude < 2)
         {
             //it's usually not a good idea to alter a rigidbodies velocity every frame
             //but this is the cleanest way i could think of, and we have a lot of checks beforehand, so it shou
             rigidbody.velocity = Vector3.zero;
         }
     }
     
     //returns whether we are on the ground or not
     //also: bouncing on enemies, keeping player on moving platforms and slope checking
     private bool IsGrounded() 
     {
         //get distance to ground, from centre of collider (where floorcheckers should be)
         float dist = collider.bounds.extents.y;
         //check whats at players feet, at each floorcheckers position
         foreach (Transform check in floorCheckers)
         {
             RaycastHit hit;
             if(Physics.Raycast(check.position, Vector3.down, out hit, dist + 0.05f))
             {
                 if(!hit.transform.collider.isTrigger)
                 {
                     //slope control
                     slope = Vector3.Angle (hit.normal, Vector3.up);
                     //slide down slopes
                     if(slope > slopeLimit && hit.transform.tag != "Pushable")
                     {
                         Vector3 slide = new Vector3(0f, -slideAmount, 0f);
                         rigidbody.AddForce (slide, ForceMode.Force);
                     }
                     //enemy bouncing
                     if (hit.transform.tag == "Enemy" && rigidbody.velocity.y < 0)
                     {
                         enemyAI = hit.transform.GetComponent<EnemyAI>();
                         enemyAI.BouncedOn();
                         onEnemyBounce ++;
                         dealDamage.Attack(hit.transform.gameObject, 1, 0f, 0f);
                     }
                     else
                         onEnemyBounce = 0;
                     //moving platforms
                     if (hit.transform.tag == "MovingPlatform" || hit.transform.tag == "Pushable")
                     {
                         movingObjSpeed = hit.transform.rigidbody.velocity;
                         movingObjSpeed.y = 0f;
                         //9.5f is a magic number, if youre not moving properly on platforms, experiment with this number
                         rigidbody.AddForce(movingObjSpeed * movingPlatformFriction * Time.fixedDeltaTime, ForceMode.VelocityChange);
                     }
                     else
                     {
                         movingObjSpeed = Vector3.zero;
                     }
                     //yes our feet are on something
                     return true;
                 }
             }
         }
         movingObjSpeed = Vector3.zero;
         //no none of the floorchecks hit anything, we must be in the air (or water)
         return false;
     }
     
     //jumping
     private void JumpCalculations()
 
 
     {
         //keep how long we have been on the ground
         groundedCount = (grounded) ? groundedCount += Time.deltaTime : 0f;
         
         //play landing sound
         if(groundedCount < 0.25 && groundedCount != 0 && !audio.isPlaying && landSound && rigidbody.velocity.y < 1)
         {
             audio.volume = Mathf.Abs(rigidbody.velocity.y)/40;
             audio.clip = landSound;
             audio.Play ();
         }
         //if we press jump in the air, save the time
 
 
         if (Input.GetButtonDown ("Jump") && !grounded)
 
                         Jump (dbljump);
 
         //if were on ground within slope limit
         if (grounded && slope < slopeLimit)
         {
             //and we press jump, or we pressed jump justt before hitting the ground
             if (Input.GetButtonDown ("Jump") || airPressTime + jumpLeniancy > Time.time)
             {    
                 //increment our jump type if we haven't been on the ground for long
                 onJump = (groundedCount < jumpDelay) ? Mathf.Min(2, onJump + 1) : 0;
                 //execute the correct jump (like in mario64, jumping 3 times quickly will do higher jumps)
                 if (onJump == 0)
                         Jump (jumpForce);
                 else if (onJump == 1)
                         Jump (secondJumpForce);
                 else if (onJump == 2)
                         Jump (thirdJumpForce);
             }
         }
     }
     
     //push player at jump force
     public void Jump(Vector3 jumpVelocity)
 
     {
         if(jumpSound)
         {
             audio.volume = 1;
             audio.clip = jumpSound;
             audio.Play ();
         }
         rigidbody.velocity = new Vector3(rigidbody.velocity.x, 0f, rigidbody.velocity.z);
         rigidbody.AddRelativeForce (jumpVelocity, ForceMode.Impulse);
         airPressTime = 0f;
     }
 }
 
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by CrazyPenguin · Mar 30, 2014 at 11:14 AM

Perhaps the code for limiting the amount of button downs to 2 which resets every time player is grounded?

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by BokuDev · Aug 14, 2014 at 08:06 AM

Attach this to your player.

using UnityEngine; using System.Collections;

public class DoubleJumpEnabler : MonoBehaviour {

 //This will be used to only allow the double jump if it's before highest jump point. Or not, you choose!
 public bool CanAfterHighestJumpPoint=true;
 
 //We'll use this to communicate with the playerMove.
 private PlayerMove playerMove;
 
 //This is to keep track if we have double jumped already or if we can double jump      
 private bool CanDoubleJump = true;
 //In case of us wanting to only double jump if we're still going up on our jump, we need to store the last Y position.
 private float LastY;
 //We'll pick the grounded bool from the Animator and store here to know if we're grounded.
 private bool GroundedBool;
 
 // Use this for initialization
 void Start () {
     //Pick the Player Move component
     playerMove = GetComponent<PlayerMove>();
 }
 
 // Update is called once per frame
 void Update() {
     //If we receive a jump button down, we're not grounded and we can double jump...
     if (Input.GetButtonDown ("Jump") && !GroundedBool && CanDoubleJump) {
         //Do a jump with the first jump force! :D
         playerMove.Jump (playerMove.jumpForce);
         //And lets set the double jump to false!
         CanDoubleJump=false;
     }
 }
 
 //This is an udpate that is called less frequently
 void FixedUpdate () {
     //Let's pick the Grounded Bool from the animator, since the player grounded bool is private and we can't get it directly..
     GroundedBool = playerMove.animator.GetBool("Grounded");
     //If I can't double jump...
     if(!CanDoubleJump) {
         //But I'm grounded
         if(GroundedBool){
             //Then I should turn my Double Jump to on because I can certainly double jump again.
             CanDoubleJump=true;
         }
     }
     //If shouldn't be able to double jump after reaching the highest jump point, we'll need this part of the code
     if(!CanAfterHighestJumpPoint) {
         //If i'm not grounded
         if(!GroundedBool){
             //If my current Y position is less than my Previously recorded Y position, then I'm going down
             if(gameObject.transform.position.y<LastY) {
                 //So, I'm going down, I shouldn't be able to double jump anymore.
                 CanDoubleJump=false;
             }
             //Anyways, lets record the LastY position for a check later.
             LastY=gameObject.transform.position.y;
         }
     }
 }

}

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple jump C# Script. 2 Answers

How do i incorporate a double jump ingame? 1 Answer

Jumping through the roof! 1 Answer

Double Jump makes my character fly into the sky 4 Answers

Multiple Cars not working 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges