I appear sinking into the ground

First of all, since I’m a newbie, I don’t even know if I’m asking this in the correct format. Basically I have a floor with a box collider, and on top of it a player (capsule) with the main camera paired with the player, the player has a rigidbody, the playermovement script and the capsule collider. I attach photos:

Además, adjunto el script:

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public float speed = 5f;
    public float mouseSensitivity = 100f;
    public Transform playerBody;
    private Rigidbody rb;

    private float xRotation = 0f;
    private bool isGrounded;

    void Start()
    {
        rb = GetComponent<Rigidbody>();

        if (rb == null)
        {
            Debug.LogError("No se encontró un Rigidbody en el jugador.");
        }

        Cursor.lockState = CursorLockMode.Locked;
    }

    void Update()
    {
        isGrounded = IsGrounded();

        if (isGrounded)
        {
            Debug.Log("El jugador está tocando el suelo.");
        }
        else
        {
            Debug.Log("El jugador no está tocando el suelo.");
        }

        float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
        float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;

        xRotation -= mouseY;
        xRotation = Mathf.Clamp(xRotation, -90f, 90f);
        playerBody.localRotation = Quaternion.Euler(xRotation, 0f, 0f);

        transform.Rotate(Vector3.up * mouseX);
    }

    void FixedUpdate()
    {
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        Vector3 movement = transform.forward * vertical + transform.right * horizontal;
        rb.MovePosition(rb.position + movement * speed * Time.fixedDeltaTime);
    }

    private bool IsGrounded()
    {
        RaycastHit hit;
        if (Physics.Raycast(transform.position, Vector3.down, out hit, 1f))
        {
            Debug.Log("Colisión con: " + hit.collider.name);
            return true;
        }
        return false;
    }
}

I don’t think anyone will answer me, but I’ve had this problem for days and the only thing I have left to try is to ask here. Thank you very much in advance if anyone answers me.

Don’t use input in FixedUpdate, this will miss some of the input as FixedUpdate runs at 50 Hz (default).

The IsGrounded check is performed with the object’s position. If the Raycast already starts inside a collider, it will not register the hit. So if your transform.position is at the “feet” of the player object, it will likely sink into the ground and fall through.

And if your player collider is not centered on the object and the object isn’t exactly two units high you will also see it partially offset from the floor since you raycast downwards by exactly one unit.

You should really use the built-in CharacterController. At the very least, make the rigidbody kinematic since dynamic rigidbody motion is awkward for controlling a character and leads to really odd issues, such as being pushed against the player’s input. Use non-kinematic controllers only for a game that utilizes this sort of whacky behaviour, eg one of those physics-based fighting games.

It looks like you’ve placed the floor’s box collider onto the player. Remove the box collider.

You may also consider not using MovePosition to move your character around as it won’t be reliably blocked by collisions. Instead use AddForce. Or if you don’t want inertia then use a character controller. But keep in mind that the character controller isn’t truly frame rate independent and so it may behave a little differently on machines with high frame rates.

It’s okay to use Input.GetAxis in FixedUpdate. Input is only a problem in FixedUpdate when using Input.GetKey.

It’s also okay to use a non kinematic rigidbody for a character. Inertia and momentum aren’t whacky. It’s just physics. :slight_smile: