首页 > 解决方案 > Unity:在更新中不能可靠地检测到 Input.GetButtonDown?

问题描述

我有一个正在尝试实现的播放器脚本。问题是Input.GetButtonDown("Jump")在更新中不会始终触发。我知道这是在 FixedUpdate 中的问题。这是我的代码。

笔记:我穿上[SerializeField]pressingJumpholdingJump所以我可以看到发生了什么。pressingJump不一致(如预期的那样),但holdingJump效果很好。

using UnityEngine;

public class Player : MonoBehaviour
{
    public float fallMultiplier = 15f;
    public float lowJumpMultiplier = 10f;
    public float walkSpeed = 20f;
    public float jumpSpeed = 15f;

    public bool canMove = true;
    public bool canJump = true;
    
    Rigidbody rb;

    float horizontalInput;
    bool doJump;
    bool pressingJump;
    bool holdingJump;
    
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        CaputureInput();
    }

    void CaputureInput()
    {
        if (canMove) {
            horizontalInput = Input.GetAxisRaw("Horizontal");
        }
        

        pressingJump = Input.GetButtonDown ("Jump");
        doJump = pressingJump && canJump;
        holdingJump = Input.GetButton ("Jump") && canJump;
    }
    
    void FixedUpdate()
    {
        Move();
        Jump();
    }
    
    void Move()
    {
        rb.velocity = new Vector2(horizontalInput * walkSpeed, rb.velocity.y);
    }
    
    void Jump()
    {
        if (doJump) {
            rb.velocity += Vector3.up * jumpSpeed;
            doJump = false;
        }

        if (rb.velocity.y < 0) {
            rb.velocity += Vector3.up * Physics.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
        } else if (rb.velocity.y > 0 && !holdingJump) {
            rb.velocity += Vector3.up * Physics.gravity.y * (lowJumpMultiplier - 1) * Time.deltaTime;
        }        
    }
}

标签: unity3d

解决方案


好的,在这里找到了解决方案:https ://www.reddit.com/r/Unity3D/comments/9nr2sd/inputgetbuttondown_and_getbuttonup_dont_work/e7ogta1?utm_source=share&utm_medium=web2x

这是我遇到的问题。

编辑:评论指出链接可能不被接受。这是来自链接的相关内容。它指出了问题发生的原因以及如何解决它。

使用您编写的代码最终得到的结果与在 FixedUpdate 中进行输入检查时的结果基本相同。

这是因为 Update 在每个 FixedUpdate 之间运行多次。现在,在这种情况下,这对您的代码意味着什么,是的,您确实在 Update 期间捕获了 ButtonDown("Jump") 的状态,但请考虑一下:如果另一个 Update 在 FixedUpdate 之前发生,button_down/up_jump 会发生什么?GetButtonDown 和 GetButtonUp 都是仅对发生按键/释放的那一帧有效的函数。换句话说,这正在发生

更新运行 -> button_down_jump 为假

用户按下“跳转”。

更新运行 -> button_down_jump 为真

更新运行 -> button_down_jump 为假

FixedUpdate 运行 -> 没有任何反应,因为 button_down_jump 的状态

现在,您实际上已经遇到了一些情况,您可以在正确的时间按下/取消按下“跳转”以设法打印任何内容。只有在发生以下情况时才会发生这种情况:

用户取消/按“跳转”

更新运行(一次)

FixedUpdate 运行

你真正想做的是这样的:

无效更新(){ if(Input.GetButtonDown(“jump”)){ button_down_jump = true; //这会捕获一帧之外的布尔值状态,因为它仅在输入事件发生时设置 } if(Input.GetButtonUp("jump")) { button_up_jump = true; } }


推荐阅读