Unity 3D, player stuck on wall? [Solved]

Overview:
I have a first person character controller (shown below) attached to a GameObject with a capsule colider and rigidbody.

Issue:
When the character is told to walk into a wall they will stop being affected by gravity and will simply float.

Any help would be greatly appreciated.

Current Player Controller Code: (updated after the reply made by: adi7b9)

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

public class Player : MonoBehaviour
{
    [Header("Movement")]
    [Tooltip("Walk speed in units per second.")] public float walkSpeed;
    [Tooltip("Sprint speed in units per second.")] public float sprintSpeed;
    [Tooltip("Air control speed in units per second.")] public float airSpeed;
    [Tooltip("Jump force applied upwards.")] public float jumpForce;

    [Header("Camera")]
    [Tooltip("Mouse look sensitivity.")] public float lookSensitivity;
    [Tooltip("Highest we can look.")] public float maxLookX;
    [Tooltip("Lowest we can look.")] public float minLookX;
    private float rotationX;    //  current x rotation of camera

    private Camera cam;
    [SerializeField] private Rigidbody rb;

    private void Awake()
    {
        //  get the camera
        cam = Camera.main;

        //  disable the cursor
        Cursor.lockState = CursorLockMode.Locked;
    }

    private void Update()
    {
        CameraLook();
    }

    private void FixedUpdate()
    {
        Movement();
    }

    private void Movement()
    {
        //Checking if the player is on the ground
        if (Grounded())
        {
            if (Input.GetKey(KeyCode.LeftControl))
                Move(sprintSpeed);
            else
                Move(walkSpeed);
            Jump();
        }
        else
        {
            Move(airSpeed);
        }
    }

    private bool Grounded()
    {
        Ray ray = new Ray(transform.position, Vector3.down);

        if (Physics.Raycast(ray, 1.1f))
            return true;
        else
            return false;
    }

    private void Move(float speed)
    {
        //  get the keyboard inputs
        float x = Input.GetAxis("Horizontal") * speed;
        float z = Input.GetAxis("Vertical") * speed;

        // convert global direction to local direction
        Vector3 dir = transform.right * x + transform.forward * z;
        dir.y = rb.velocity.y;

        // apply the velocity
        rb.velocity = dir;
    }

    private void Jump()
    {
        if (Input.GetButtonDown("Jump"))
        {
            rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
        }
    }

    private void CameraLook()
    {
        // get the mouse inputs
        float y = Input.GetAxis("Mouse X") * lookSensitivity;
        rotationX += Input.GetAxis("Mouse Y") * lookSensitivity;

        // Set max look up and down
        rotationX = Mathf.Clamp(rotationX, minLookX, maxLookX);

        // rotate player and camera
        cam.transform.localRotation = Quaternion.Euler(-rotationX, 0, 0);
        transform.eulerAngles += Vector3.up * y;
    }
}

This still doesn’t fix the issue that I have, the player can still avoid being affected by gravity by simply walking into a wall

The reason your stopping is because your force vector is at an upwards angle & pushing into the wall, so you want to make it more directly upwards.

If you raycast ahead of the controller to get the surface hit you can use the wall normal to help negate the forward veloctity.

something like this should work (untested):

        RaycastHit hit;
        if(Physics.Raycast(transform.position, dir, out hit, dir.magnitude))
        {
            float dirMag = dir.magnitude;

            Vector3 wallNormal = hit.normal;
            //We don't want to effect our y speed so null it
            wallNormal.y = 0.0f;
            wallNormal.Normalize();

            //How much are we trying to walk into the surface
            float wallDot = Vector3.Dot(dir.normalized, wallNormal);

            //Make our wall normal the same length as our movement vector & then adjust for how much we are trying to walk into this wall
            dir -= (wallNormal * dirMag) * wallDot;
        }
1 Like

(My interpretation i’m kinda new).
Are you basically saying if the player is walking into a wall, to cancel out the forward movement so they simply drop

Yes, but to cancel out the momentum travelling towards the wall, so your y velocity will then be able to take over.

Okay thanks, that has sorted it out, my only issue is I do not know where to put your code from above

Stick it in your move function, after “Vector3 dir = transform.right * x + transform.forward * z;” & before “dir.y = rb.velocity.y;”