Hey Guys I have a problem with a single jump script.

I’m working on a adventure rpg and trying to set up a simple single jump action. For some reason each time I test there is a double jump or even a way to cheese the timing to mini jump forever. Can someone look over my noob code and let me know if I goofed somewhere?

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

public class Player : MonoBehaviour
{
    
    public float speed;
    public float jumpForce;
    public float turningSpeed;

    private bool canJump;

    
    void Start()
    {
        
    }

    
    void Update()
    {
        
        RaycastHit hit;
        if (Physics.Raycast(transform.position, Vector3.down, out hit, 1.01f))
        {
            canJump = true;
        }
        
        ProcessInput();
        
    }


    void ProcessInput ()
    {
        if (Input.GetKey("right") || Input.GetKey("d"))
        {
            transform.position += Vector3.right * speed * Time.deltaTime;

        }

        if (Input.GetKey("left") || Input.GetKey("a"))
        {
            transform.position += Vector3.left * speed * Time.deltaTime;

        }

        if (Input.GetKey("up") || Input.GetKey("w"))
        {
            transform.position += Vector3.forward * speed * Time.deltaTime;
        }

        if (Input.GetKey("down") || Input.GetKey("s"))
        {
            transform.position += Vector3.back * speed * Time.deltaTime;
        }

        if ( Input.GetKeyDown("space") && canJump)
        {

            GetComponent<Rigidbody>().AddForce(0, jumpForce, 0);
            canJump = false;
        }

        
    }
}

Try this:
Add a empty GameObject to character(It has to be at the ground level). Then add this code to your code. After that attach the GameObject to controller.Then add layer to your ground object.And set the ground_layer varilable to ground. And bada bing bada bam. It has to be work .

    public Transform controller;
    public bool canJump;
    public LayerMask ground_layer;
    const float grounded_time= 0.2f;

void Update()
{
     canJump=Physics.OverlapSphere(controller.position, ground_time, ground_layer);

     if ( Input.GetKeyDown("space") && canJump)
     {
         GetComponent<Rigidbody>().AddForce(0, jumpForce, 0);
     }
}

I’m guessing it has to do with your raycast. Likely there is a few frames after the jump key is pressed where the raycast still intersects the ground and sets canJump to true again as the character is traveling up. A quick fix would be to add a small delay before canJump can be set back to true after you’ve jumped.