- Home /
Unity2D Platformer - Wall jumping with unity's physics
Hello!
I'm fairly new to Unity, as I've only worked on one other project besides this one. However, I'm not new to C# nor coding in general.
Basically my problem is, is that when I wall jump from one wall to another, the player's rigidbody doesn't fully come into contact with the wall, and what's more the player kinda bounces off of the wall, so the player can't wall jump from the wall. There is a physics material on the wall, but its values are both zero for friction and bounce. I'm also using add force to allow the player to move in the air, and I'm assigning velocity to jump, double jump and wall jump. I do however have two colliders on my character, one circle and one box. If anyone needs a video/gif of this occuring, I'd be happy to. I'd like to have the player be able to wall jump between walls until they get to the top.
Is there anyway to make a rigidbody2D come in full contact with a wall?
Here's my code, though it may be a tad confusing to read:
using UnityEngine;
using System.Collections;
public class PlayerContoller : MonoBehaviour
{
public float walkSpeed = 25f;
public float runSpeed = 45f;
public float pushForce = 150f; //the amount of pull you have in the air
public float jumpForce = 50f;
public float wallJumpPushForce = 40f;
public float wallJumpForce = 40f;
public float fastFallFactor = 40f;
float jumpSpeed;
float pushForceLimiter; //Limits how fast you can move in the air with AddForce()
float normalGravity;
float direction;
float move;
bool running;
bool facingRight = true;
bool jumped = false; //Has no function at the moment
bool doubleJump = true;
bool superJump = true; //Has no function at the moment
bool wallJumped = false;
bool fastFalling = false;
bool grounded;
bool touchingWall;
bool touchedWall;
float checkRadius = 0.2f;
public Transform groundCheck;
public Transform wallCheck;
public LayerMask whatIsGround;
void Start()
{
normalGravity = rigidbody2D.gravityScale; //This value is 15.
pushForceLimiter = walkSpeed;
}
void FixedUpdate()
{
direction = Input.GetAxis("Horizontal");
running = Input.GetButton("Run");
grounded = Physics2D.OverlapCircle(groundCheck.position, checkRadius, whatIsGround);
touchingWall = Physics2D.OverlapCircle(wallCheck.position, checkRadius, whatIsGround);
move = direction * (((running ? 1 : 0) * runSpeed) + ((running ? 0 : 1) * walkSpeed));
if (grounded)
{
rigidbody2D.velocity = new Vector2(move, rigidbody2D.velocity.y);
}
else
{
rigidbody2D.AddForce(new Vector2(direction * pushForce, 0));
if (Mathf.Abs(rigidbody2D.velocity.x) > pushForceLimiter)
{
rigidbody2D.velocity = new Vector2(direction * pushForceLimiter, rigidbody2D.velocity.y);
}
}
if (fastFalling)
rigidbody2D.gravityScale = normalGravity * fastFallFactor;
if (grounded)
{
doubleJump = true;
jumped = false;
superJump = true;
wallJumped = false;
pushForceLimiter = ((running ? 1 : 0) * runSpeed) + ((running ? 0 : 1) * walkSpeed);
if (fastFalling)
{
fastFalling = false;
rigidbody2D.gravityScale = normalGravity;
}
}
else if(touchingWall && !touchedWall) //An attempt to solve the problem, but it didn't work.
{
if (!wallJumped)
{
rigidbody2D.velocity = new Vector2(0, rigidbody2D.velocity.y);
touchedWall = true;
}
else wallJumped = false;
}
if (rigidbody2D.velocity.x > 0 && !facingRight)
Flip();
else if (rigidbody2D.velocity.x < 0 && facingRight)
Flip();
}
void Update()
{
bool jump = Input.GetButtonDown("Jump");
bool fall = Input.GetButtonDown("Fall");
if (jump)
{
if (grounded)
{
Debug.Log("Jump!");
jumped = true;
rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, jumpForce);
}
else if (touchingWall)
{
Debug.Log("Wall jump!");
pushForceLimiter = wallJumpPushForce;
//These next two variables are ones I made specifically to solve this issue.
touchedWall = false;
wallJumped = true;
rigidbody2D.velocity = new Vector2(wallJumpPushForce * (facingRight ? -1 : 1), wallJumpForce);
}
else if (doubleJump)
{
Debug.Log("Double jump!");
rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, jumpForce / 1.1f);
doubleJump = false;
}
}
if (fall)
if (rigidbody2D.velocity.y > -20 && rigidbody2D.velocity.y < 0)
fastFalling = true;
}
void Flip()
{
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
//Ignore this. Faild attempt at a solution.
void OnCollisionEnter2D(Collision2D collision) {
if(collision.collider.tag == "Block")
{
if (!grounded)
{
rigidbody2D.velocity = new Vector2(0, 0);
Debug.Log("Hit Wall!");
}
}
}
}
Thanks for any insight that you all can provide me!
Answer by kupot · May 04, 2015 at 11:23 AM
I ran into a similar problem myself using the Physics2D.OverlapCircle function. Instead, using Raycasts you can do a whole lot more. I would suggest looking into using Raycasts for ground and wall detection - that way if the players rigidbody doesnt touch the wall (as you're experiencing) the raycast will be able to detect your proximity to the wall and take action when the wall is a certain distance from your player object.
Your answer
Follow this Question
Related Questions
3d wall jumping with charter controller 1 Answer
Issues with Mecanim and climbing 1 Answer
Need Scripts for wall forward to behind and climb 0 Answers
Jump with a wallrun 0 Answers
HELP! stuck on wall jump Unity 2D 1 Answer