So I have very specific requirements for my jumping mechanic.
- 2D
- Pressure sensitive; hold button for short time, short jump, hold for longer, longer jump
- Double jump
- Uses a state machine, so when calling jump function, use state = State.Jump ()
- Do this in the most efficient way
I’ve been working at this for far too long and have exhausted all things I could think of Starting to wonder if using a state machine for jumping isn’t going to work.
Any help would be greatly appreciated!
Some of the code (the problem is when I call NextState inside JumpState enum, it causes JumpState to loop, which causes infinite jumps instead of only a max of 2):
// Start NextState
void NextState ()
{
// If is visible
if (isVisible)
{
string methodName = state.ToString () + "State";
System.Reflection.MethodInfo info = GetType().GetMethod (methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
StartCoroutine ((IEnumerator)info.Invoke (this, null));
} // End if visible
} // End NextState
// Start FixedUpdate
void FixedUpdate ()
{
// If is not dead
if (state != State.Dead)
{
// If y velocity is less than 0 (negative)
if (rb.velocity.y < 0)
{
// Fall faster than you rose
rb.AddForce (Vector2.down * randFallNum);
}
// If any input
if (Input.anyKey)
{
// If is grounded
if (isGrounded)
{
// If jump input
if (Input.GetButtonDown ("Jump"))
{
// Set state
state = State.Jump;
} // End jump input
} // End if grounded
// If not grounded
if (!isGrounded)
{
// If any input
if (Input.anyKey)
{
// If jump input and can double jump
if (Input.GetButtonDown ("Jump") && canDoubleJump)
{
// Set state
state = State.Jump;
// Set vars
canDoubleJump = false;
} // End if jump input
} // End if any input
} // End if not grounded
// Else if no input
else if (!Input.anyKey)
{
// If grounded
if (isGrounded)
{
// Set state
state = State.Idle;
} // End if grounded
} // End if no input
} // End of if dead
} // End of FixedUpdate
// Start Jump
IEnumerator JumpState ()
{
yield return 0;
// Set vars
rb.velocity = new Vector2 (rb.velocity.x, 0);
// If running
if (speed == runSpeed)
{
// Jump
rb.AddForce (transform.up * jumpForceRun, ForceMode2D.Impulse);
}
// If not running
if (speed == walkSpeed)
{
// Jump
rb.AddForce (transform.up * jumpForce, ForceMode2D.Impulse);
}
// Call function
NextState ();
} // End Jump