/// <summary>pretends to hold the jump button for the specified duration</summary> public void FixedUpdate(CharacterMove p) { if (inputHeld = (PressJump > 0)) { PressJump -= Time.deltaTime; } if (impulseActive && !inputHeld) { impulseActive = false; } if (!inputHeld) { return; } bool isStableOnGround = p.IsStableOnGround(); // check stable footing for the jump if (isStableOnGround) { jumpsSoFar = 0; heightReached = 0; currentJumpVelocity = 0; timeHeld = 0; } // calculate the jump float gForce = -Physics.gravity.y * p.rb.mass; Vector3 jump_force = Vector3.zero, jumpDirection = Vector3.up;//-p.gravity.dir; // if the user wants to jump, and is allowed to jump again if (!impulseActive && (jumpsSoFar < maxJumps)) { heightReached = 0; timeHeld = 0; jumpsSoFar++; targetHeight = minJumpHeight * p.rb.mass; float velocityRequiredToJump = Mathf.Sqrt(targetHeight * 2 * gForce); // cancel out current jump/fall forces if (jumpStartResetsVerticalMotion) { float motionInVerticalDirection = Vector3.Dot(jumpDirection, p.rb.velocity); jump_force -= (motionInVerticalDirection * jumpDirection) / Time.deltaTime; } // apply proper jump force currentJumpVelocity = velocityRequiredToJump; peaked = false; jump_force += (jumpDirection * currentJumpVelocity) / Time.deltaTime; impulseActive = true; } else // if a jump is happening if (currentJumpVelocity > 0) { // handle jump height: the longer you hold jump, the higher you jump if (inputHeld) { timeHeld += Time.deltaTime; if (timeHeld >= fullJumpPressDuration) { targetHeight = maxJumpHeight; timeHeld = fullJumpPressDuration; } else { targetHeight = minJumpHeight + ((maxJumpHeight - minJumpHeight) * timeHeld / fullJumpPressDuration); targetHeight *= p.rb.mass; } if (heightReached < targetHeight) { float requiredJumpVelocity = Mathf.Sqrt((targetHeight - heightReached) * 2 * gForce); float forceNeeded = requiredJumpVelocity - currentJumpVelocity; jump_force += (jumpDirection * forceNeeded) / Time.deltaTime; currentJumpVelocity = requiredJumpVelocity; } } } else { impulseActive = false; } if (currentJumpVelocity > 0) { float moved = currentJumpVelocity * Time.deltaTime; heightReached += moved; heightReachedTotal += moved; currentJumpVelocity -= gForce * Time.deltaTime; } else if (!peaked && !isStableOnGround) { peaked = true; impulseActive = false; } p.rb.AddForce(jump_force); }