Raycast Ground Check

Hey, folks. I’ve pored over documentation but I cannot seem to figure out why this code will not let me jump if grounded:

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.UpArrow) == true) // if spacebar or up
        {
            print("key pressed!");
            bool grounded = (Physics.Raycast(playerBox.transform.position, Vector3.down, 1f, LayerMask.NameToLayer("Ground"))); // raycast down to look for ground is not detecting ground? only works if allowing jump when grounded = false; // return "Ground" layer as layer
            if (grounded == true)
            {
                print("grounded!");
                jump();
            }
        }
    }

I can only jump if I set grounded == true to grounded == false. Then it allows me to jump repeatedly.

Thanks in advance

1 Like

This isn’t a game design question, so I hope it gets moved to an appropriate place.
However it’s pretty obvious you’re never grounded (raycast evaluates to false) and so you can’t jump. Why that happens, you need figure out yourself, since it depends on a lot of things that nobody can see over the internet.

1 Like

I understand that part – I should have been more clear. I have a rigidbox character (playerBox) with a 2d collider sitting atop a platform 2d collider with the layer “Ground”. Even when it is sitting directly on top of the “Ground” layer platform, it still does not detect ground.

It’s difficult to tell from your code but it looks like it might not be hitting the ground because you are raycasting from the point that is already on (or slightly below) the ground - i.e. the rigid body point. When you raycast to the ground it’s always a good idea to start the raycast from a point that’s higher up. For example, take the playerBox.transform.position and add a metre upwards vector it. You’ll then need to make sure your raycast length is slightly larger.

2 Likes

I’d put money on it! I’ll try it when I get home. Thanks!

No dice… I bumped the y up a bit and added a Debug.Drawray to confirm it’s working and the ray is penetrating the “Ground” platform. For some reason, I still do not show grounded as == 1 – see here: Imgur: The magic of the Internet. The entirety of my code is attached.

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

public class gameController : MonoBehaviour {

    public Rigidbody2D playerBox; // allows me to manipulate rigidbox globally -> set in editor

    // Use this for initialization
    void Start () {
        gameBegin();
        GameObject startingPlat = GameObject.Find("Cube");
        startingPlat.layer = LayerMask.NameToLayer("Ground");
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.UpArrow) == true) // if spacebar or up
        {
            print("key pressed!");
            bool grounded = (Physics.Raycast((new Vector2(playerBox.transform.position.x, playerBox.transform.position.y + 1f)), Vector3.down, 2f, 1 << LayerMask.NameToLayer("Ground"))); // raycast down to look for ground is not detecting ground? only works if allowing jump when grounded = false; // return "Ground" layer as layer
            Debug.DrawRay((new Vector3(playerBox.transform.position.x, playerBox.transform.position.y + 1f, playerBox.transform.position.z)), Vector3.down, Color.green, 5);

            if (grounded == true)
            {
                print("grounded!");
                jump();
            }
            else if (grounded == false)
            {
                print("Can't Jump - Not Grounded");
            }
        }
    }

    void FixedUpdate()
    {
        movePlats();
    }

    void gameBegin()
    {
        createPlat();
    }

    void createPlat()
    {

    }

    void movePlats()
    {

    }

    void jump()
    {
        int jumpSpeed = 500;
        playerBox.AddForce(new Vector2(0, jumpSpeed));
        print("jump!");
    }
}

You say that the debug ray is going through the floor? If your floor is a 2d line / object, maybe the ray is not actually colliding with it. I wonder if making the floor a 3d object that has some Z depth could help. Otherwise, maybe it could be a layer issue. You have your mask set, but maybe you don’t have it properly assigned to the floor or the mask isn’t working right. Maybe making your layer using a bitshift with an integer for the layer number would help.

int mask = 1 << 10;    // Ground on layer 10 in the inspector

if(Physics.Raycast(playerBox.transform.position,
    Vector3.down,
    out hit,
    _raycastDistance,
    mask)) {

    grounded = true;
 }

Using mask as the argument and ensuring that your “Floor” layer is on layer 10 for example.

Since this is 2D you need to use Physics2D.Raycast

Link to docs here: Unity - Scripting API: Physics2D.Raycast

1 Like

A huge thank you to everyone who replied, but this was the fix. I have no idea why, since the sample code I was using was what I had used during a previous tutorial and I’d swear up and down it was using 3d rays on 2d colliders, but I’m not going to lose any sleep over it. Thank you!

sideways?

Please do not necro post. Start your own post. It’s free.

How to report your problem productively in the Unity3D forums:

http://plbm.com/?p=220

This is the bare minimum of information to report:

  • what you want
  • what you tried
  • what you expected to happen
  • what actually happened, especially any errors you see
  • links to documentation you used to cross-check your work (CRITICAL!!!)

If you post a code snippet, ALWAYS USE CODE TAGS:

How to use code tags: https://discussions.unity.com/t/481379