0
\$\begingroup\$

I'm developping a 2D platformer and i'm facing a little trouble. I'm actually trying to develop a Wall detection and the possibility to Wall Jump and go in the opposite direction. I'm able to detect Walls and when i press the jump button my player goes nuts. I actually made a little video to show you what's going on + my code :

Speed x 15 (on the code i only multiply the force on X by 15) = http://youtu.be/zeK8RTVQdiU
Normal Speed = http://youtu.be/GvW_x0hd7wk

Here is my code

#pragma strict
var moveSpeed : float = 600;
var jumpSpeed : float = 25;
var fallSpeed : float = 64;
var maxFallSpeed : float = 60;
var maxUpSpeed : float = 25;
var slopeLimit : float = 45;
var onGround : boolean;
var touchLeft : boolean;
var touchRight : boolean;
var justBounced : boolean;
var contactAgainst : boolean;

private var vm : float;
private var xScale : float;
private var h : float;
private var v : float;
private var jump : boolean;
private var boxCollider : BoxCollider2D; //If boxCollider2D is used replace w/ ...     private var boxColl : BoxCollider2D;
private var circleCollider : CircleCollider2D;
private var vectorRight : Vector2;
private var vectorLeft : Vector2;

function Start () {
    xScale = transform.localScale.x; //Get correct starting Orientation for player.
    boxCollider = GetComponent(BoxCollider2D); //if boxCollider2D is used replace w/... boxColl = GetComponent(BoxCollider2D);
   circleCollider = GetComponent(CircleCollider2D);
    var vectorLeft = Vector2(Vector3.left.x, Vector3.left.y);
    var vectorRight = Vector2(Vector3.right.x, Vector3.right.y);
}

function Update () {
    h = Input.GetAxisRaw("Horizontal"); //get horizontal input
    v = Input.GetAxisRaw("Vertical"); //get vertical input
    jump = Input.GetKey(KeyCode.Space); //get jump input
    if((touchLeft || touchRight) && contactAgainst) {
        var forceSaut : float;
        if(touchLeft && !touchRight && jump) {
            h = 1;
            forceSaut = h * moveSpeed * Time.deltaTime;
            Debug.Log(forceSaut);
            rigidbody2D.AddForce(Vector2.right * forceSaut); //Apply horizontal movement
            rigidbody2D.AddForce(Vector2.up * jumpSpeed); //Apply vertical movement
            justBounced = false;
        }
        else if(!touchLeft && touchRight && jump) {
            h = -1;
            forceSaut = h * moveSpeed * Time.deltaTime;
            Debug.Log(forceSaut);
            justBounced = true;
            rigidbody2D.AddForce(Vector2.right * forceSaut * 15); //Apply horizontal movement
            rigidbody2D.AddForce(Vector2.up * jumpSpeed * 3); //Apply vertical movement
        }
        else {
//              Debug.Log("collision et contre un mur !");
        }
    }
}

function FixedUpdate(){
    if(onGround && jump && !touchLeft && !touchRight){ //Are we grounded can we jump?
            vm = jumpSpeed;
    }
    if(justBounced)
        h = 0;
    var moveH : float = h * moveSpeed * Time.deltaTime; //Smooth horizontal movement
    //Flip character orientation
    if(h < 0){
            transform.localScale.x = -xScale;
    } else if(h > 0){
            transform.localScale.x = xScale;
    }

    rigidbody2D.AddForce(Vector2.right * moveH); //Apply horizontal movement
    rigidbody2D.AddForce(Vector2.up * vm); //Apply vertical movement

    vm -= fallSpeed * Time.deltaTime;

    vm = Mathf.Clamp(vm, -maxFallSpeed, maxUpSpeed); //Clamp vertical speeds
    rigidbody2D.velocity = Vector2.zero; //Stop movement if there is no input
    onGround = touchLeft = touchRight = false;
    checkPositionCollision();
}

function OnCollisionEnter2D(c : Collision2D){
CheckCollision(c);
}

function OnCollisionStay2D(c : Collision2D){
CheckCollision(c);
}

function OnCollisionExit2D(c : Collision2D) {
contactAgainst = false;
}

function CheckCollision(c : Collision2D){
for(var contact in c.contacts){
        if(vm <= 0 && contact.point.y <= transform.position.y - ((circleCollider.radius * transform.localScale.y + transform.localScale.y) / 2) && Vector2.Angle(Vector2.up, contact.normal) <= slopeLimit){
                onGround = true;
                justBounced = false;
                vm = Mathf.Max(0, vm);
                contactAgainst = true;
        }
//          if(vm <= 0 && contact.point.y <= transform.position.y - ((boxCollider.size.y * transform.localScale.y) / 2) && Vector2.Angle(Vector2.up, contact.normal) <= slopeLimit){
//                  onGround = true;
//                  vm = Mathf.Max(0, vm);
//          }
}
}

function checkPositionCollision() {
    var yCircle = transform.localPosition.y + (circleCollider.center.y * transform.localScale.y);
    var circlePosition = Vector3(transform.localPosition.x , yCircle, transform.localPosition.z);
    var hitRight = Physics2D.Raycast(circlePosition, transform.right, circleCollider.radius * transform.localScale.y + transform.localScale.y,  1 << LayerMask.NameToLayer("Walls"));
    var hitLeft = Physics2D.Raycast(circlePosition, -transform.right, circleCollider.radius * transform.localScale.y + transform.localScale.y,  1 << LayerMask.NameToLayer("Walls"));
    if(hitRight) {
        touchRight = true;
        justBounced = false;
    }
    if(hitLeft) {
        touchLeft = true;
        justBounced = false;
    }
}

Thanks for your help :)

\$\endgroup\$

closed as off-topic by bummzack, Vaughan Hilts, Sean Middleditch, Josh Apr 7 '14 at 16:40

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions about debugging a problem in your project must present a concise selection of code and context so as to allow a reader to diagnose the issue without needing to read all of your code or to engage in extensive back-and-forth dialog. For more information, see this meta thread." – bummzack, Vaughan Hilts, Sean Middleditch, Josh
If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ Hi there, generally large code dumps are not useful to post here. If you could isolate your question a bit and make it easier for others to digest, you might find greater help. \$\endgroup\$ – Vaughan Hilts Apr 6 '14 at 19:03
1
\$\begingroup\$

So this is just a guess but I think your problem stems from applying Force in your update method.

Try if you can, to move any code that adds force in the fixed update method.

Also you might want to try to calculate just one vector to apply force too rather than mixing two addforce together unity may not be mixing them like you would expect them to be.

\$\endgroup\$
0
\$\begingroup\$

Well, i answered the question by myself, recreating completly the class, here is my code :

using UnityEngine; using System.Collections;

public class PlayerController : MonoBehaviour {

public bool onGround = false;
public bool jump = false;
public float maxSpeedX = 3f;
public float maxSpeedY = 3f;
public LayerMask whatIsGround;
public Transform groundChecker;

private float groundRadius = 0.1f;
private bool facingRight = true;
public bool touchLeft = false;
public bool touchRight = false;
private CircleCollider2D circleCollider;

public float velocityX;
public float velocityY;

void Start () {
    circleCollider = GetComponent<CircleCollider2D>();
}

void FixedUpdate () {
    float forceX = 0;
    float forceY = 0;
    velocityX = rigidbody2D.velocity.x;
    velocityY = rigidbody2D.velocity.y;
    //Je test si mon personnage est collé à un mur
    checkWallPosition();

    onGround = Physics2D.OverlapCircle (groundChecker.position, groundRadius, whatIsGround);
    float moveH = Input.GetAxisRaw ("Horizontal");
    jump = Input.GetButtonDown("Jump");

    //Si je touche le sol
    if (onGround) {
        if(moveH != 0) {
            forceX = maxSpeedX * moveH;
        }
        if(jump && !touchLeft && !touchRight) {
            forceY = maxSpeedY;
        }
        else if(jump && (touchLeft || touchRight)) {
            if(touchLeft) {
                forceX = maxSpeedX;
            }
            else {
                forceX = -maxSpeedX;
            }
            forceY = maxSpeedY;
            Flip ();
        }
        else {
            forceY = rigidbody2D.velocity.y;
        }
    } 


    //Si je ne touche pas le sol
    else {
        if(!jump && !touchLeft && !touchRight) {
            forceY = rigidbody2D.velocity.y;
            forceX = rigidbody2D.velocity.x;
        }
        else if(jump && (touchLeft || touchRight)) {
            if(touchLeft) {
                forceX = maxSpeedX;
                if(!facingRight)
                    Flip ();
            }
            else {
                forceX = -maxSpeedX;
                if(facingRight)
                    Flip ();
            }
            forceY = maxSpeedY;
        }
        else if(touchLeft || touchRight) {
            if(moveH == 0) {
                forceX = 0;
                forceY = rigidbody2D.velocity.y;
            }
            else {
                if((touchLeft && moveH == -1) || (touchRight && moveH == 1)) {
                    if(moveH == -1 && facingRight) {
                        Flip ();
                    }
                    if(moveH == 1 && !facingRight) {
                        Flip ();
                    }
                    forceY = rigidbody2D.velocity.y / 3;
                }
            }
        }
    }


    //Ici les forces sont appliquées
    rigidbody2D.velocity = new Vector2 (forceX, forceY);


    //Ici le personnage est retourné en fonction de sa position
    if (onGround) {
        if (moveH > 0 && !facingRight) {
            Flip ();
        }
        else if (moveH < 0 && facingRight) {
            Flip ();
        }
    }

}

private void Flip(){
    facingRight = !facingRight;
    Vector3 theScale = transform.localScale;
    theScale.x *= -1;
    transform.localScale = theScale;
}

private void checkWallPosition() {
    touchLeft = touchRight = false;
    float yCircle = transform.localPosition.y + (circleCollider.center.y * transform.localScale.y);
    Vector3 circlePosition = new Vector3(transform.localPosition.x , yCircle, transform.localPosition.z);
    bool hitRight = Physics2D.Raycast(circlePosition, transform.right, circleCollider.radius * transform.localScale.y + transform.localScale.y,  1 << LayerMask.NameToLayer("Walls"));
    bool hitLeft = Physics2D.Raycast(circlePosition, -transform.right, circleCollider.radius * transform.localScale.y + transform.localScale.y,  1 << LayerMask.NameToLayer("Walls"));
    if(hitRight) {
        touchRight = true;
    }
    if(hitLeft) {
        touchLeft = true;
    }
}
}
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.