首页 > 解决方案 > FixedUpdate 不注册所有键(统一)

问题描述

我订购了一本书,我一直完全按照它的说明进行操作。唯一的问题是,当我将动作放入 FixedUpdate 时,它​​不会注册每个键。我已经阅读了很多答案,但他们都说将您的输入放入 Update 并将所有物理放入 FixedUpdate。我就是这么做的,但是当我按空格键 30 次时,它只会跳到 5 左右。这是我的一些代码(如果它的可读性不好,我很抱歉,我才刚刚开始。):

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

public class PlayerBehavior : MonoBehaviour
{

    public GameObject bullet;

    public float moveSpeed = 10f;
    public float rotateSpeed = 10f;
    public float jumpVelocity = 5f;
    public float distanceToGround = 0.1f;
    public float bulletSpeed = 100f;

    public LayerMask groundLayer;

    private float vInput;
    private float hInput;

    private Rigidbody _rb;
    private CapsuleCollider _col;

    private bool isShooting;
    private bool isJumping;

    void Start()
    {
        _rb = GetComponent<Rigidbody>();
        _col = GetComponent<CapsuleCollider>();

        isShooting = false;
        isJumping = false;
    }


    void Update()
    {
        //player movement
        vInput = Input.GetAxis("Vertical") * moveSpeed;
        hInput = Input.GetAxis("Horizontal") * rotateSpeed;

        isJumping = Input.GetKeyDown(KeyCode.Space);

        //allows me to see if the spacer bar is registering
        if (isJumping)
        {
            Debug.Log("Jump");

        }

        isShooting = Input.GetMouseButtonDown(1);

        if (isShooting)
        {
            Debug.Log("Shoot");
        }
    }

    void FixedUpdate()
    {

        Vector3 rotation = Vector3.up * hInput;
        Quaternion angleRot = Quaternion.Euler(rotation * Time.fixedDeltaTime);
        _rb.MovePosition(this.transform.position + this.transform.forward * vInput * 
        Time.fixedDeltaTime);
        _rb.MoveRotation(_rb.rotation * angleRot);

        //determines if the player is on the ground and hit the spacebar. If so the player jumps.
        if (IsGrounded() && isJumping)
        {
            _rb.AddForce(Vector3.up * jumpVelocity, ForceMode.Impulse);

        //this allows isJumping to revert back to false 100% of the time

            isJumping = false;

            Debug.Log("The jump mechanic is working");
        }

        if (isShooting)
        {
            GameObject newBullet = Instantiate(bullet, this.transform.position + new Vector3(1, 0, 0), 
            this.transform.rotation) as GameObject;
            Rigidbody bulletRB = newBullet.GetComponent<Rigidbody>();
            bulletRB.velocity = this.transform.forward * bulletSpeed;

            isShooting = false;
            Debug.Log("The shooting mechanic is working");
        }
    }


    //determines if the player is on the ground
    bool IsGrounded()
    {
        Vector3 capsuleBottom = new Vector3(_col.bounds.center.x, _col.bounds.min.y, 
        _col.bounds.center.z);
        bool grounded = Physics.CheckCapsule(_col.bounds.center, capsuleBottom, distanceToGround, 
        groundLayer, QueryTriggerInteraction.Ignore);

        return grounded;
    }
}

标签: unity3d

解决方案


FixedUpdate每 200 毫秒左右调用一次,具体取决于您将 FixedUpdate 间隔设置为什么。 Update每帧调用一次。

GetKeyDown在您按目标键true确切帧上返回KeyCode。在它返回的每隔一帧false

如果您调用GetKeyDown中的每一帧UpdateisJumping将是您true按下键的确切帧,以及每隔一帧false

现在想象一下这会如何影响不是每帧都调用FixedUpdate的方法。可以设置为和before甚至被调用一次。IsJumpingtruefalseFixedUpdate

您基本上只想设置IsJumpingtrueinUpdate然后将其设置为falsein FixedUpdate

您的 Update 方法最终应如下所示:

void Update()
{
    //player movement
    vInput = Input.GetAxis("Vertical") * moveSpeed;
    hInput = Input.GetAxis("Horizontal") * rotateSpeed;
    
    if(Input.GetKeyDown(KeyCode.Space)){
        isJumping = true;
    }

    if(Input.GetMouseButtonDown(1)){
        isShooting= true;
    }
}

推荐阅读