Problem with BoxCast 3D

Im making a 3-D game and i want to do ground check. Since the object is 3-D, instead of using a rayCast im using a BoxCast. I created an empty game object that stores the orign of boxcast. I created a boxCast from that gameObject downwards (-transform.up OR Vector3.down).
I used a gizmo as well to keep a track of the box.
There is a small probelm tho. As soon as the box touches the ground, the player is slowing down and after reaching the ground, onGround is getting disabled and movement is getting disabled. What am i doing wrong?

using UnityEngine;

public class PlayerMovementScript : MonoBehaviour
{
    [SerializeField] float speed;
    [SerializeField] float groundDist;
    [SerializeField] bool onGround;

    [SerializeField] LayerMask terrainLayer;
    [SerializeField] Rigidbody rb;
    [SerializeField] Vector3 boxSize;
    [SerializeField] Transform boxcastOrign;

    private void Start()
    {
        rb = gameObject.GetComponent<Rigidbody>();
    }

    private void FixedUpdate()
    {
        // onGround = Physics.Raycast(transform.position, Vector3.down, groundDist, terrainLayer);
        onGround = Physics.BoxCast(boxcastOrign.position, boxSize / 2, -transform.up, Quaternion.identity, boxSize.y, terrainLayer);
        if (onGround)
        {
            Debug.Log(onGround);
        }

        if (onGround)
        {
            float xValue = Input.GetAxis("Horizontal");
            float yValue = Input.GetAxis("Vertical");

            Vector3 moveDirection = new Vector3(xValue, 0, yValue);

            rb.velocity = moveDirection * speed;
        }
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        // Gizmos.DrawLine(transform.position, transform.position + Vector3.down * groundDist);
        Gizmos.DrawWireCube(boxcastOrign.position, boxSize);
    }
}

Importantbug-ezgif.com-video-to-gif-converter

I tried a solution where i disable gravity as soon as onGround is true.

if (onGround)
        {
            disableGravity();
        }

        else
        {
            enableGravity();
        }

        if (onGround)
        {
            float xValue = Input.GetAxis("Horizontal");
            float yValue = Input.GetAxis("Vertical");

            Vector3 moveDirection = new Vector3(xValue, 0, yValue);

            rb.velocity = moveDirection * speed;
        }
void enableGravity()
    {
        rb.useGravity = true;
    }

    void disableGravity()
    {
        rb.useGravity = false;
    }

This does work but i need to know why it wasnt working previously.

And if you can, please tell me how can i prevent the clipping of objects JUST AT THE EDGE of the camera. I am thinking of making this game either Isomertric OR Top Down; which one would be better?

Note: I will refer to the red cube as ‘cube’ and the ‘ground check box’ as ‘box’

First, it looks like your box is underneath the cube, so once the cube is touching the ground, the box is underneath the ground and no longer touching - no more onGround. Perhaps move the box up a little so it intersects with the cube.

Second, you remove all y-velocity from the cube. That’s why it slows down as soon as the box touches the ground. You are fighting gravity here. Gravity tries to accelerate the cube down, and then you set it back to 0. Don’t do that. Change the movement code to include the y-velocity

Vector3 moveDirection = new Vector3(xValue, rb.velocity.y, yValue) * speed;

A note: Don’t get input in the FixedUpdate. Get the input in Update and then use it in FixedUpdate. Something like

private Vector2 _movementVector;
private void Update()
{
    _movementVector = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
}
private void FixedUpdate()
{
    // ... your ground check code is in here somewhere
    if (onGround)
    {
        rb.velocity = new Vector3(_movementVector.x, rb.velocity.y, _movementVector.y) * speed;
    }
}

This is because you are using an orthographic camera and the objects are moving ‘behind’ the camera. I personally never use orthographic cameras, even when I do isometric views. Check this (old) post on setting up a isometric cameras for both orthographic and perspective cameras. Imo, perspective looks better than orthographic. The clipping in orthographic cameras are always gonna happen when objects move ‘behind’ the camera. It’s too much of a hassle for me to bother with, so I’ve always just opted for low FOV perspective cameras. Orthographic is really for 2D games and the depth never really changes so there isn’t generally issues with objects going behind the camera like that and clipping

Thank you soo much!! This is very comprehensive and useful!!!

But one thing. In the GIF that I attached, towards the end, you can see that the box IS intersecting the cube. So the GroundCheck not working as intended doesn’t make any sense.

Is the Gizmo actually reflecting whatever the box actually is? Or is there some difference between what the Gizmo is showing and what the actual box is?

I don’t know. I looked at the miniature gif and tried to make out what’s happening and that’s where it looked like the box is under the cube. That’s why I said “it looks like your box is underneath the cube”. I looked at it again carefully and can now see that it’s overlapping (the red gizmo on the red cube didn’t help).

The gizmo doesn’t show the correct thing. A BoxCast is like a raycast, but it casts a box instead of a ray. In your case, it is casting a 5x1x5 (looks like a 5) box 1 unit down from the origin. Rays don’t hit colliders they’re inside of (unless you configure them to), so I think once you hit the ground the ray is being cast from inside the terrain and no longer hitting. I think what you want is Physics.OverlapBox which is what your gizmo represents.

This is a mistake. This will multiply the y-velocity with speed as well. It should rather be

Vector3 moveDirection = new Vector3(xValue * speed, rb.velocity.y, yValue * speed);

So how do i implement it? It says that it returns a collider. Now how do i convert this collider into bool?

Its an array of colliders tbh.

OK, so colliders.Length > 0 should tell you that you collided with something. If that’s false, it means you collided with nothing

Ooo that makes sense. Its now working perfectly! Thank you!!

I’m glad bixarrio was able to help you. If the problem is solved, could you please mark an answer as the solution?


See also:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms