- Home /
[C#] Make my 2D character jump in FixedUpdate
So, i'm trying to reproduce the Meatboy CharacterController (Meatboy, not Super Meatboy) I'm having a problem on the jump (Well, i have to precise i'm really new in C# and Unity in general)
When i press Space, my character is bumping for like 0.1s, then falling down automatically with gravity. What i'd like to do is making him jump for a while (maybe 1.5seconds), then slowing and falling down. And if possible, i would like to do eveything in FixedUpdate (i added some lines in Update, i want to replace them). I see that the problem for the 0.1sec jump is because my Jumping goes from true to false right after i pressed Space, but i don't know how to fix it.
I hope you can help me on this, because i don't really see how i can do this.
Here is my code now:
using UnityEngine;
using System.Collections;
public class MeatboyController : MonoBehaviour {
bool onWallLeft = false;
bool onWallRight = false;
bool onGround = false;
bool Jumping = false;
private float Gravity = 4;
private float Vitesse = 10;
private KeyCode Left = KeyCode.LeftArrow;
private KeyCode Right = KeyCode.RightArrow;
private KeyCode Jump = KeyCode.Space;
private float CDJump = 2;
void FixedUpdate () {
Vector2 targetPos = rigidbody2D.position - Vector2.up * Gravity * Time.fixedDeltaTime;
if (onWallLeft == false && onGround == false && onWallRight == false) {
if (Input.GetKey (Left)) targetPos = rigidbody2D.position - (Vector2.right * Vitesse * Time.fixedDeltaTime) - (Vector2.up * Gravity * Time.fixedDeltaTime);
if (Input.GetKey (Right)) targetPos = rigidbody2D.position + (Vector2.right * Vitesse * Time.fixedDeltaTime) - (Vector2.up * Gravity * Time.fixedDeltaTime);
}
if (onGround == true) {
if (Input.GetKey (Left)) targetPos = rigidbody2D.position - (Vector2.right * Vitesse * Time.fixedDeltaTime) - (Vector2.up * Gravity * Time.fixedDeltaTime);
if (Input.GetKey (Right)) targetPos = rigidbody2D.position + (Vector2.right * Vitesse * Time.fixedDeltaTime) - (Vector2.up * Gravity * Time.fixedDeltaTime);
}
if (onWallLeft == true && onGround == false && onWallRight == false) {
if (Input.GetKey (Right)) targetPos = rigidbody2D.position + (Vector2.right * Vitesse * Time.fixedDeltaTime) - (Vector2.up * Gravity * Time.fixedDeltaTime);
}
if (onWallLeft == false && onGround == false && onWallRight == true) {
if (Input.GetKey (Left)) targetPos = rigidbody2D.position - (Vector2.right * Vitesse * Time.fixedDeltaTime) - (Vector2.up * Gravity * Time.fixedDeltaTime);
}
if(Jumping == true){
rigidbody2D.AddForce(transform.up*700);
Jumping = false;
}
rigidbody2D.MovePosition( targetPos );
}
void Update () {
if (Jumping == false) {
if (Input.GetKeyDown (Jump)) {
Jumping = true;
}
}
}
void OnCollisionEnter2D(Collision2D collision)
{
for (int i = 0; i < collision.contacts.Length; i++) {
if(collision.contacts[i].normal.x > 0) {
onWallLeft = true;
}
if(collision.contacts[i].normal.x < 0) {
onWallRight = true;
}
if(collision.contacts[i].normal.y != 0) onGround = true;
}
}
void OnCollisionExit2D(Collision2D collision)
{
for (int i = 0; i < collision.contacts.Length; i++) {
if(collision.contacts[i].normal.x > 0) onWallLeft = false;
if(collision.contacts[i].normal.x < 0) onWallRight = false;
if(collision.contacts[i].normal.y != 0) onGround = false;
}
}
void OnGUI()
{
GUILayout.Label("on left wall:" + onWallLeft.ToString());
GUILayout.Label("on right wall:" + onWallRight.ToString());
GUILayout.Label("on ground:" + onGround.ToString());
GUILayout.Label("is jumping:" + Jumping.ToString());
}
}
When I was program$$anonymous$$g a controller for 2D platformers, I found that setting velocities directly was easier to control than applying forces. I.e. something like this rigidBody.velocity += Vector.up * speed
(pseudocode).
The same also applies to left/right movement. You can do something like rigidBody.velocity = Vector.right * Input.GetAxis("Horizontal")
ins$$anonymous$$d of having multiple if statements.
The nice thing about setting velocities is that it bypasses friction, so you don't have to worry about that sliding effect that some games have (unless you want them).
A sample FixedUpdate would look something like this (pseudocode):
void FixedUpdate() {
// Horizontal movement
rigidbody.velocity = Input.GetAxis("Horizontal") * Vector.right * moveSpeed
// Jumping
if (/* start of jump */) {
rigidbody.velocity += Vector.up * jumpSpeed
}
// Nothing else needs to go here for basic movement
}
Also, note that Unity automatically handles collisions and gravity, so you don't need to implement gravity yourself. Just check gravity in the rigidbody component in the inspector. Collisions should work automatically as long as you don't try to set the position of the rigidbody yourself.
Your answer
Follow this Question
Related Questions
How to fix a infinity jump? 1 Answer
Camera follow player jumping? 2 Answers
Input.GetButtonDown inconsistent 1 Answer
In air direction control 4 Answers
C# Jumping Issue 1 Answer