- Home /
2D Wall Jump and Wall Friction
EDIT: Wall Friction is taken care of. Just need Wall-Jumping now
First off, I want to say I'm very novice when it comes to coding. So I'm going to need some guidance here with these two issues.
I watched the Live Training 16 video which covers 2D character controller. Here's the Link. So I got the character moving, got double jump working. I two questions. First is an issue with sticking to walls. If I am holding a direction, jump at a wall, and hold that direction, my character will stick to the wall and not slide down. I'm searching the web for an answer, and I'm supposed to do something with no friction.
My second thing is, using this code, how do I add wall-jumping?
Here's the code that I have, which is from that video I linked above. If someone can help me out with this, please be specific with step-by-step instructions. Thanks in advance!
using UnityEngine;
using System.Collections;
public class CharacterControllerScript : MonoBehaviour {
public float maxSpeed = 10f;
bool facingRight = true;
Animator anim;
//sets up the grounded stuff
bool grounded = false;
public Transform groundCheck;
float groundRadius = 0.2f;
public LayerMask whatIsGround;
public float jumpForce = 700f;
//double jump
bool doubleJump = false;
// Use this for initialization
void Start () {
anim = GetComponent<Animator>();
}
// Update is called once per frame
void FixedUpdate () {
// The player is grounded if a linecast to the groundcheck position hits anything on the ground layer.
grounded = Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround);
anim.SetBool("Ground", grounded);
if (grounded) {
doubleJump = false;
}
anim.SetFloat ("vSpeed", rigidbody2D.velocity.y);
float move = Input.GetAxis ("Horizontal");
anim.SetFloat("Speed", Mathf.Abs (move));
rigidbody2D.velocity = new Vector2(move * maxSpeed, rigidbody2D.velocity.y);
// If the input is moving the player right and the player is facing left...
if(move > 0 &&!facingRight){
// ... flip the player.
Flip ();
}// Otherwise if the input is moving the player left and the player is facing right...
else if(move < 0 && facingRight){
// ... flip the player.
Flip ();
}
}
void Update(){
// If the jump button is pressed and the player is grounded then the player should jump.
if((grounded || !doubleJump) && Input.GetButtonDown("Jump")){
anim.SetBool("Ground", false);
rigidbody2D.AddForce(new Vector2(0, jumpForce));
if(!doubleJump && !grounded){
doubleJump = true;
}
}
}
void Flip(){
// Switch the way the player is labelled as facing
facingRight = !facingRight;
//Multiply the player's x local cale by -1
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
Answer by DricoJD · Feb 20, 2014 at 11:43 AM
Okay, here is an answer to your wall sticking:
Step One:
Right click in your Project window and create a new physics material, then put the settings to that there is no friction.
Step two:
Go to the colliders of your walls and assign it that way.
Now to make your character wall jump:
Copy the GameObject groundcheck in Unity. and put it to the middle of the player and just right of the player. Call it "Wall Check"
Now, and please add this script, it is an edited version of your script so just copy and paste over your whole script.
using UnityEngine;
using System.Collections;
public class CharacterControllerScript : MonoBehaviour {
public float maxSpeed = 10f;
bool facingRight = true;
Animator anim;
//sets up the grounded stuff
bool grounded = false;
bool touchingWall = false;
public Transform groundCheck;
public Transform wallCheck;
float groundRadius = 0.2f;
float wallTouchRadius = 0.2f;
public LayerMask whatIsGround;
public LayerMask whatIsWall;
public float jumpForce = 700f;
public float jumpPushForce = 10f;
//double jump
bool doubleJump = false;
// Use this for initialization
void Start () {
anim = GetComponent<Animator>();
}
// Update is called once per frame
void FixedUpdate () {
// The player is grounded if a linecast to the groundcheck position hits anything on the ground layer.
grounded = Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround);
touchingWall = Physics2D.OverlapCircle(wallCheck.position, wallTouchRadius, whatIsWall);
anim.SetBool("Ground", grounded);
if (grounded)
{
doubleJump = false;
}
if (touchingWall)
{
grounded = false;
doubleJump = false;
}
anim.SetFloat ("vSpeed", rigidbody2D.velocity.y);
float move = Input.GetAxis ("Horizontal");
anim.SetFloat("Speed", Mathf.Abs (move));
rigidbody2D.velocity = new Vector2(move * maxSpeed, rigidbody2D.velocity.y);
// If the input is moving the player right and the player is facing left...
if(move > 0 &&!facingRight){
// ... flip the player.
Flip ();
}// Otherwise if the input is moving the player left and the player is facing right...
else if(move < 0 && facingRight){
// ... flip the player.
Flip ();
}
}
void Update()
{
// If the jump button is pressed and the player is grounded then the player should jump.
if((grounded || !doubleJump) && Input.GetButtonDown("Jump"))
{
anim.SetBool("Ground", false);
rigidbody2D.AddForce(new Vector2(0, jumpForce));
if(!doubleJump && !grounded)
{
doubleJump = true;
}
}
if (touchingWall && Input.GetButtonDown ("Jump"))
{
WallJump ();
}
}
void WallJump ()
{
rigidbody2D.AddForce (new Vector2 (jumpPushForce, jumpForce));
}
void Flip(){
// Switch the way the player is labelled as facing
facingRight = !facingRight;
//Multiply the player's x local cale by -1
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
Now I will need you to save the script go back to unity and assign the wallCheck variable in the Inspector. Also assign the other variables like WhatIsWall (LayerMask). create a Layer called "Wall" and assign your walls layers to "Wall".
I tried out the new script, wall jumping works but sometimes the player will make one really big super jump. Do you know what might be causing this issue?
Usually that's caused by the jump not quite taking them out of range of the ground on the first frame - they still register as grounded on the first frame of their jump, and still have jump held down, so the jumping force is applied again. To avoid that, have a set number of frames after a jump (about 5 should be fine) before the character can be considered grounded again. I've never handled wall-jumping, but I guess the same problem will be possible.