1
\$\begingroup\$

I have a 2D platformer game and in it I have recently implemented wall jumping, and the way I have it works great. However when one jumps with the character and moves towards the wall one can hold themselves stationary against the wall. This is something that I do not want. This is due to unity's inbuilt physics and is something that I would like to modify. I was wondering what the best way to go about this would be? This was quite difficult for me to explain and if you don't understand please don't hesitate to ask questions.

EDIT: Since the code was demanded I have it here: however I don't think it is to do with my code, I think that it is to do with the physics that unity employs.

using UnityEngine;
using System.Collections.Generic;

public class Player_Movement : MonoBehaviour {
    public bool facingRight = true; 
    public float moveForce = 365f;          // Amount of force added to move the player left and right.
    public float maxSpeed = 5f;             // The fastest the player can travel in the x axis.
    public float jumpForce = 1000f;         //force added on jump
    private Transform groundCheck;
    private Transform [] leftWallCheck,rightWallCheck;  // A position marking where to check if the player is grounded.
    private bool grounded = false;  
    private bool jump=false;
    public float speed;
    public int dubJumpDivisor;
    private bool dubjump=false;
    private bool wallJumpEnabled,WallJumping;//prevents continuous wall jumping
    private List <HillSpawner> hillMovement;


    void Start(){

        hillMovement = new List<HillSpawner> ();
        //  hillMovement=GameObject.FindGameObjectWithTag("HillSpawners").GetComponent<HillSpawner>();
        GameObject[] hills=GameObject.FindGameObjectsWithTag("HillSpawners");
        for(int i = 0; i<hills.Length; i++){
            hillMovement.Add (hills[i].GetComponent<HillSpawner>());
        }

    }
    void Awake () {
        int aloc =0 , bloc =0;
        leftWallCheck=new Transform[2];
        rightWallCheck=new Transform[2];
        foreach(Transform b in transform){
            if(b.name=="leftWallCheck"){
                leftWallCheck[aloc]=b;
                aloc++;
            }
            if(b.name=="rightWallCheck"){
                rightWallCheck[bloc]=b;
                bloc++;
            }
        }
        // Setting up references.
        groundCheck = transform.Find("groundCheck");

    }
        // Update is called once per frame
    void Update () {
        // Check if grounded
        bool wallJump=false;
        grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("level"));  
        if(Physics2D.Linecast(transform.position, leftWallCheck[0].position, 1 << LayerMask.NameToLayer("level")) ||Physics2D.Linecast(transform.position, rightWallCheck[0].position, 1 << LayerMask.NameToLayer("level"))||Physics2D.Linecast(transform.position ,leftWallCheck[1].position, 1 << LayerMask.NameToLayer("level")) ||Physics2D.Linecast(transform.position, rightWallCheck[1].position, 1 << LayerMask.NameToLayer("level"))){
            wallJump = true; 
            }else{
            wallJumpEnabled = true;
        }


        if(wallJump&&wallJumpEnabled&&(Input.GetButtonDown("Jump")&&!grounded)){
            wallJumpEnabled = false;
                WallJumping =true;

        }

        if(Input.GetButtonDown("Jump")&&!dubjump){

            if(!grounded){
                dubjump=true;
            }

            jump=true;
        }
        movement();
    }
    void LateUpdate(){
        if(WallJumping){
            jumpUp((int)(jumpForce));
            WallJumping = false;
        }
        if(jump)//first jump
        {

            if(dubjump){
                // Add a vertical force to the player.
                jumpUp((int)(jumpForce/dubJumpDivisor));
            }else{
                // Add a vertical force to the player.
                jumpUp((int)(jumpForce));
            }






            // Make sure the player can't jump again until the jump conditions from Update are satisfied.
            jump=false;
        }

        if(grounded){dubjump=false;}
        movement();
    }
    void movement(){
        float h = Input.GetAxis("Horizontal");
        if(h * rigidbody2D.velocity.x < maxSpeed){
            // ... add a force to the player.
            rigidbody2D.AddForce(Vector2.right * h * moveForce);


        }
        // If the player's horizontal velocity is greater than the maxSpeed...
        if(Mathf.Abs(rigidbody2D.velocity.x) > maxSpeed){
            // ... set the player's velocity to the maxSpeed in the x axis.
            rigidbody2D.velocity = new Vector2(Mathf.Sign(rigidbody2D.velocity.x) * maxSpeed, rigidbody2D.velocity.y);
            //          backgroundUpdate.run(1.0f);

        }
        // If the input is moving the player right and the player is facing left...
        if(h > 0 && !facingRight)
            // ... flip the player.
            Flip();
        // Otherwise if the input is moving the player left and the player is facing right...
        else if(h < 0 && facingRight)
            // ... flip the player.
            Flip();

        // If the player should jump...
        for(int i =0; i<hillMovement.Count; i++){
            hillMovement[i].move(-h);
        }
        speed= Input.GetAxis("Horizontal");
    }
    private void jumpUp(int i){
        rigidbody2D.velocity=new Vector2(rigidbody2D.velocity.x,0f);//this sets y velocity to zero, should this be done

        rigidbody2D.AddForce(new Vector2(0f, i));

    }

    void Flip(){}
}

One solution that I can think of is to simply modify the friction value in the vertical plane, unfortunately I have no idea as to how to accomplish this. If you can tell me how then that would be great. EDIT: this is in unity 2d

\$\endgroup\$
  • 2
    \$\begingroup\$ And this is a great example of why physics engines and platformers don't mix. See also learn-cocos2d.com/2013/08/… \$\endgroup\$ – Sean Middleditch Feb 27 '14 at 1:57
  • \$\begingroup\$ So am I going to have to make my own physics stuff? This is really sad for unity 2D if all it can do is render \$\endgroup\$ – user1814893 Feb 27 '14 at 2:56
  • 1
    \$\begingroup\$ To get even passable platforming behaviour, you have to heavily customise/override the behaviour of any typical rigid-body physics engine. Although you don't have to necessarily ditch it entirely. Walking is not the same thing as boxes, etc, sliding and bouncing around. \$\endgroup\$ – Andrew Russell Feb 27 '14 at 4:54
  • 1
    \$\begingroup\$ I had this same issue and I just added a physics material to the player with 0 friction... Worked fine :) \$\endgroup\$ – Savlon Feb 27 '14 at 5:40
  • \$\begingroup\$ savlon that is what I have been thinking of doing, but I was wondering if you knew a way to only have this apply to the vertical axis? Otherwise I'll either have to set the friction everytime they double jump, and get in contact with the ground again, or I'll have to do my own friction for the walking. \$\endgroup\$ – user1814893 Feb 27 '14 at 6:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.