Ben Whittaker

Ground and Slope Detection in Unity

I was helping a friend of mine figure out ground and slope detection for his Unity-based platformer, and I whipped up this example project. It’s actually pretty simple, if you do it right.

You can download the project here, or scroll down to view the code attached to the player entity.

GroundCheckExample.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GroundedCheckExample : MonoBehaviour {

    public int movementforce = 10;
    public float groundCheckScaleAdjustment = 0.95f;
    public float groundCheckDistance = 0.1f;
    public int groundLayer = 8;

    bool grounded;
    float slope; // Rise over run

    Rigidbody2D body;
    BoxCollider2D box;

    // Use this for initialization
    void Start () {
        body = GetComponent<Rigidbody2D>();
        box = GetComponent<BoxCollider2D>();
    }

    // Update is called once per frame
    void Update () {
        body.AddForce(new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")) * movementforce);

        RaycastHit2D hit = Physics2D.BoxCast(transform.position, box.size * groundCheckScaleAdjustment, 0, Vector2.down, groundCheckDistance, 1 << groundLayer);
        if (hit.collider != null)
        {
            grounded = true;
            slope = -hit.normal.x / hit.normal.y;
        }
        else
        {
            grounded = false;
        }

        // A positive value for slope indicates an upwards slope, a negative value indicates a downwards slope
        // If slope == -Mathf.Infinity, that means that it's detected a pure vertical slope, ie. a wall. If groundScaleAdjustment is set to something reasonable, this shouldn't happen very often.
        Debug.Log("Grounded: " + grounded + (grounded ? (", Slope: " + slope) : ""));
    }
}