
[英]Unity Editor Doesn't Detect Rigidbody Component in the FixedUpdate Method
[英]FixedUpdate doesn't register all keys (unity)
我订购了一本书,我一直完全按照它的说明进行操作。 唯一的问题是,当我将动作放入 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;
}
}
FixedUpdate
每 200 毫秒左右调用一次,具体取决于您设置的 FixedUpdate 间隔。 每帧调用一次Update
。
GetKeyDown
在您使用您所定位的KeyCode
按下 Key 的确切帧上返回true
。 在每隔一帧它返回false
。
如果您在Update
中的每一帧都调用GetKeyDown
,那么对于您按下键的确切帧, isJumping
将是true
,并且每隔一帧它将是false
。
现在想象一下这会如何影响不是每帧都调用的FixedUpdate
方法。 在调用FixedUpdate
IsJumping
设置为true
和false
甚至一次。
您基本上只想在Update
中将IsJumping
设置为true
,然后在FixedUpdate
其设置为false
。
您的 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;
}
}
每帧都会调用Update
。
FixedUpdate
在某些时间间隔内,但通常比Update
少。
GetKeyDown
和GetMouseButtonDown
仅对恰好一帧为true
,即按下开始的那一帧。
代替
isJumping = Input.GetKeyDown(KeyCode.Space);
在下一帧中已经将值重置为false
- 很可能在FixedUpdate
之前 - 你宁愿这样做
if(Input.GetKeyDown(KeyCode.Space))
{
isJumping = true;
}
和相应的isShooting
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.