The problem of using rigid body to manipulate the character to jump in Unity (no response when pressing the space bar to jump)

question:

During the learning process of the fifth edition of "Introduction to Unity and C# Game Programming", the practice on page 196 of the book - press the space bar to make the player jump, and after writing the script according to the code written in the book, some problems appeared after the project Play Sometimes the character does not jump when pressing the space bar, but sometimes it can jump.

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

public class Test : MonoBehaviour
{
    //速度
    public float jumpVelocity = 5f;
    private Rigidbody _rb;

    // Start is called before the first frame update
    void Start()
    {
        _rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void FixedUpdate()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            _rb.AddForce(jumpVelocity * Vector3.up, ForceMode.Impulse);

        }
    }
}

Cause of the problem

Change the code to the following form and then play

bool isJumpPressed;  //调加一个标志位
void Update()
{
    isJumpPressed = Input.GetKeyDown(KeyCode.Space);
    if (isJumpPressed)
    {            
        Debug.Log("Update Jump");
    }       
}

private void FixedUpdate()
{
    if (isJumpPressed)
    {
        Debug.Log("FixedUpdate Jump");            
    }
}

It is found that the following output appears in the Console column

 It can be found that the system prints out Update Jump many times before printing out FixedUpdate Jump once. This shows that the system calls the FixedUpdate method once after calling the Update method multiple times. The Update method in Unity is called once per frame, and FixUpdate is called once per physical update, so this explains the problem: why an object may jump once when the space bar is pressed multiple times.

Solution

You can put the if loop in the FixUpdate method directly in the Update method, but the code related to the rigid body must be placed in the FixUpdate method, so this method is not recommended.

This problem can be solved by adding a flag to record the pressing of the space bar.

public class PlayerBehavior : MonoBehaviour
{

    public float jumpVelocity = 5f;

    bool isJumpPressed;  //添加一个标志位

    private Rigidbody _rb;

    // Start is called before the first frame update
    void Start()
    {
        _rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            isJumpPressed = true;
            Debug.Log("Update Jump");
        }
    }

    //与物理(刚体)相关的代码都要放到FixedUpdate方法中
    void FixedUpdate()
    {
        if (isJumpPressed)
        {
            _rb.AddForce(jumpVelocity * Vector3.up, ForceMode.Impulse);
            Debug.Log("FixedUpdate Jump");
            isJumpPressed = false;
        }
    }
}

Play again, you can see the following results in the Console column

 Update was called once and FixUpdate was called once. Every time the space object is pressed, the object can jump, and the problem is solved.

Reference:Unity Input.GetKeyDown(KeyCode.Space) No key detected - Q&A - Tencent Cloud Developer Community - Tencent Cloud (tencent.com)

Guess you like

Origin blog.csdn.net/qq_68117303/article/details/132084433