Wall jumping

Hello, I am currently working on a 2D platform game and have made quite a lot of progress so far, I can make my character move, jump, double jump and teleport. I want to make my character able to wall jump, in other words if there are 2 walls jump between them to move up. I have tried to do it here and I have my cahracter sticking to the wall and sliding down it slowly, however you then cant move away from the wall or jump to another one, could someone point me in the right direction please? Thanks!

player Controller Script

    using UnityEngine;

using System.Collections;

[RequireComponent(typeof(PlayerPhysics))]
public class PlayerController : MonoBehaviour {

//Player handling
public float gravity = 40;
public float speed = 20;
public float acceleration = 30;
public float jumpHeight = 12;

private bool wallHolding;

private float currentSpeed;
private float targetSpeed;
private Vector2 amountToMove;

private PlayerPhysics playerPhysics;

const int MAX_JUMPS = 2;
int jumpsLeft = MAX_JUMPS;

// Use this for initialization
void Start () {

	playerPhysics = GetComponent<PlayerPhysics> ();

}

// Update is called once per frame
void Update () {

			if (playerPhysics.movementStopped) {
					targetSpeed = 0;
					currentSpeed = 0;
			}

			//Input
			targetSpeed = Input.GetAxisRaw ("Horizontal") * speed;
			currentSpeed = IncrementTowards (currentSpeed, targetSpeed, acceleration);

			if (playerPhysics.grounded) {
					jumpsLeft = MAX_JUMPS;
					amountToMove.y = 0;
			}

			//jump
			if (jumpsLeft > 0 && Input.GetButtonDown ("Jump")) {
					amountToMove.y = jumpHeight;
					jumpsLeft -= 1;
			} else {
					if (!wallHolding) {
							if (playerPhysics.canWallHold) {
									wallHolding = true;
							}
					}
			}
		

	

	amountToMove.x = currentSpeed;

	if (wallHolding) {
					amountToMove.x = 0;
					if (Input.GetAxisRaw ("Vertical") != -1) {
							amountToMove.y = 0;
					}
	}

	amountToMove.y -= gravity * Time.deltaTime;
	playerPhysics.Move (amountToMove * Time.deltaTime);
}

//Increae n towards target by speed
private float IncrementTowards(float n, float target, float a) {
			if (n == target) {
					return n;
			} 
			else {
					float dir = Mathf.Sign (target - n); //must n be increased or decreased to get closer to target
					n += speed * Time.deltaTime * dir;
					return (dir == Mathf.Sign (target - n)) ? n : target; //if n has now passed target then return target, otherwise return n
			}

	}

}

Player Physics Script

    using UnityEngine;

using System.Collections;

[RequireComponent (typeof(BoxCollider))]
public class PlayerPhysics : MonoBehaviour {

public LayerMask CollisionMask;

private BoxCollider collider;
private Vector3 s;
private Vector3 c;

private float skin = .005f;

[HideInInspector]
public bool grounded;

[HideInInspector]
public bool movementStopped;

[HideInInspector]
public bool canWallHold;

Ray ray;
RaycastHit hit;

void Start() {
			collider = GetComponent<BoxCollider> ();
			s = collider.size;
			c = collider.center;

	}

public void Move(Vector2 moveAmount) {

	float deltaY = moveAmount.y;
	float deltaX = moveAmount.x;
	Vector2 p = transform.position;

	//Check Collisions Up and Down
	grounded = false;
	for (int i = 0; i<3; i ++) {
		float dir = Mathf.Sign(deltaY);
		float x = (p.x + c.x - s.x / 2) + s.x / 2 * i; //left, centre and right part of collider
		float y = p.y + c.y + s.y / 2 * dir; //bottom of collider

		ray = new Ray (new Vector2(x,y), new Vector2(0,dir));
		//Debug.DrawRay(ray.origin, ray.direction);

		if (Physics.Raycast(ray, out hit, Mathf.Abs(deltaY)+ skin, CollisionMask)){
			//Get Distance between player and ground
			float dst = Vector3.Distance (ray.origin, hit.point);

			// stop players downwards movement when coming with skin distance of collider
			if (dst > skin) {
				deltaY = -dst - skin * dir;	
				}
			else {
				deltaY = 0;
			}
			grounded = true;
			break;
						
		}

	}

	//Check Collisions Left And Right
	movementStopped = false;
	canWallHold = false;

	if (deltaX != 0) {
					for (int i = 0; i<3; i ++) {
							float dir = Mathf.Sign (deltaX);
							float x = p.x + c.x + s.x / 2 * dir; //left, centre and right part of collider
							float y = p.y + c.y - s.y / 2 + s.y / 2 * i; //bottom of collider
			
			
							ray = new Ray (new Vector2 (x, y), new Vector2 (dir, 0));
							//Debug.DrawRay(ray.origin, ray.direction);
			
							if (Physics.Raycast (ray, out hit, Mathf.Abs (deltaX) + skin, CollisionMask)) {
								
								if (hit.collider.tag == "Wall Jump") {
									canWallHold = true;
									}

								//Get Distance between player and ground
									float dst = Vector3.Distance (ray.origin, hit.point);
				
				
									// stop players downwards movement when coming with skin distance of collider
									if (dst > skin) {
											deltaX = -dst - skin * dir;	
									} else {
											deltaX = 0;
									}

									movementStopped = true;
									break;
			
							}
			
					}

			}

	if (!grounded && !movementStopped) {
					Vector3 playerDir = new Vector3 (deltaX, deltaY);
					Vector3 o = new Vector3 (p.x + c.x + s.x / 2 * Mathf.Sign (deltaX), p.y + c.y + s.y / 2 * Mathf.Sign (deltaY));
					ray = new Ray (o, playerDir.normalized);

					if (Physics.Raycast (ray, Mathf.Sqrt (deltaX * deltaX + deltaY * deltaY), CollisionMask)) {
							grounded = true;
							deltaY = 0;
					}
			}

	Vector2 finalTransform = new Vector2(deltaX,deltaY);

	transform.Translate (finalTransform);

}

}

Try adding a jump movement in the if (wallHolding) statement in the controller.

if (wallHolding) {
   amountToMove.x = 0;
   if (Input.GetAxisRaw ("Vertical") != -1) {
      amountToMove.y = 0;
   }
   if (Input.GetButtonDown ("Jump"))
   {
      amountToMove.y = jumpHeight;
      amountToMove.x = 1 * wallSide; // jump away from the wall it's hanging on.
   }
}

Also quickly looking at the code I would add a public int on the physics side that can set the side of the wall its hanging on, e.g. 1 for a left Wall and -1 for a right wall. That way we can give a direction to the force of the controller jump.

I added that in the code snippet above as the wallSide variable, now you only need to implement it in the Physics behaviour component.

Or you could try:

amountToMove.x = currentSpeed;