domingo, 8 de noviembre de 2015

Unity 2d slopes without mathematics

Ver este post en español

So I've encounter some problems dealing with physic-based 2D platformer: slopes. Time ago I programmed Fat Ninja Adventure, that was before Unity2D came out, and this days finally I'm coding some new 2D character controller using sprites and Physics2D system.

The problem is the character 
slide down the slope. This is something not resolved in the official 2D character controller Live training -as far as I know. I've found some mathematically advanced solutions on internet, but as I'm teaching game development and not mathematics -we don't have a lot of time for long mathematical explanations-, I'm always trying to work around maths formulas :D.

Thinking about this, I've found a different solution from the mathematical approach to this problem.

public void CheckSlope()
        // Character is grounded, and no axis pressed: 
        if (grounded && axisRaw == 0 && !jump)
            RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, 10, groundLayer); 
            // Check if we are on the slope
            if (hit && Mathf.Abs(hit.normal.x) > 0.1f)
                // We freeze all the rigidbody constraints and put velocity to 0
                rigidbody.constraints = RigidbodyConstraints2D.FreezeAll;
                rigidbody.velocity =;
            // if we are on air or moving - jumping, unfreeze all and freeze only rotation.
            rigidbody.constraints = RigidbodyConstraints2D.None;
            rigidbody.constraints = RigidbodyConstraints2D.FreezeRotation;

    For the explanation, I suppose you already dealed with the grounded problem and  you know exactly when your character is grounded.    

1.- You can call this function at the end of your Update or FixedUpdate function.  the function needs to know if character is grounded, the cached horizontal axis and if you hitted the jump button this frame.    

2.- If character IS grounded, and you aren't pushing any input, it will slide. To  prevent this, we emit a raycast down and check for the normal of the impact point. This way we detect the slope. If in fact there it is, just freeze all the Rigidbody2D  and put velocity to 0. This is the trick: freeze the rigidbody.

This will prevent the moving and slide of the Rigidbody2D because of gravity -I think maybe you can change gravity modifier to 0.

 3.- If you are moving the character, or the character is in air, we just unfreeze the position -but we need still freeze the rotation, at least in my case :)   I don't know if this will work for all the cases, but in my tests is working very well, as you can see in the video. Let me know your thougts about this.

No hay comentarios:

Publicar un comentario