C# 我怎样才能解决在空中跳跃的问题?

C# 我怎样才能解决在空中跳跃的问题?,c#,unity3d,C#,Unity3d,我正在用Unity制作一个2D平台。我使用教程来编写这段代码,但做了一点修改。我想同时支持键盘和游戏板,所以我使用了新的输入系统。我定义了三个变量,分别是GroundedRememeber、jumppressedremememember和jumppressedrememembertime,它们基本上像计时器一样工作,检查球员是否离开地面,然后球员在接近地面时可以跳跃,而不需要触摸地面,我想用它来代替著名的“地面检查”。但问题是这些计时器不工作,当我快速按下跳跃按钮时,玩家甚至可以永远在空中跳跃。

我正在用Unity制作一个2D平台。我使用教程来编写这段代码,但做了一点修改。我想同时支持键盘和游戏板,所以我使用了新的输入系统。我定义了三个变量,分别是GroundedRememeber、jumppressedremememember和jumppressedrememembertime,它们基本上像计时器一样工作,检查球员是否离开地面,然后球员在接近地面时可以跳跃,而不需要触摸地面,我想用它来代替著名的“地面检查”。但问题是这些计时器不工作,当我快速按下跳跃按钮时,玩家甚至可以永远在空中跳跃。此外,正如您所见,我添加了一个名为“groundLayers”的LayerMask,让玩家只能在这类对象上跳跃,但当我在Inspector的“groundLayers”窗口中选择“Ground”时,玩家就不能再跳跃了

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

public class PlayerController : MonoBehaviour, PlayerInputActions.IPlayerActions
 {
   private PlayerInputActions controls; 
   [SerializeField] LayerMask groundLayers;     
   private Rigidbody2D rb;
   private Animator anim;
   private bool facingRight = true;
   private Vector2 moveInput;
  [SerializeField] private float jumpForce;
    float JumpPressedRemember = 0;
   
   [SerializeField] float JumpPressedRememberTime = 0.2f;
    float GroundedRemember = 0;
     
   [SerializeField]  float GroundedRememberTime = 0.25f;  
   [SerializeField]  float HorizontalAcceleration = 1;
   [SerializeField] [Range(0, 1)] float HorizontalDampingBasic = 0.5f;
   [SerializeField] [Range(0, 1)] float HorizontalDampingWhenStopping = 0.5f;
   [SerializeField] [Range(0, 1)] float HorizontalDampingWhenTurning = 0.5f;
   [SerializeField] [Range(0, 1)] float JumpHeight = 0.5f;

   private void Awake() 
   {
      controls = new PlayerInputActions();

      controls.Player.SetCallbacks(this);
    }
     void Start()
    {
      rb = GetComponent<Rigidbody2D>();
      anim = GetComponent<Animator>();       
}
   void PlayerInputActions.IPlayerActions.OnMove(InputAction.CallbackContext context)
   {
      moveInput = context.ReadValue<Vector2>();
          
   }
    void Jump() {
     rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Force);
     GroundedRemember = 0;
     JumpPressedRemember = 0;
   }

  bool TryJump() {
    if (GroundedRemember > 0) {
        Jump();
        return true;
    } else {
        JumpPressedRemember = JumpPressedRememberTime;
        return false;
    }
}
   void PlayerInputActions.IPlayerActions.OnJump(InputAction.CallbackContext context)
   {
       jumpForce = context.ReadValue<float>();
       switch (context.phase) {
            case InputActionPhase.Performed:
               TryJump();
               break;
       }
   }
  void FixedUpdate()
  {

   if(facingRight == false && moveInput.x > 0){
   
    Flip();
   
   }else if (facingRight == true && moveInput.x < 0){
    
    Flip();

   }
 }
    void Flip(){
    
    facingRight = !facingRight;
    Vector3 Scaler = transform.localScale;
    Scaler.x *= -1;
    transform.localScale = Scaler;
    
 }  
 void OnEnable()
 {
     controls.Enable();
 }
 
 void OnDisable()
{
    controls.Disable();
}
 void Update()
  {

   Vector2 GroundedBoxCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
   Vector2  GroundedBoxCheckScale = (Vector2)transform.localScale + new Vector2(-0.02f, 0);
   bool Grounded = Physics2D.OverlapBox(GroundedBoxCheckPosition, transform.localScale, 0, groundLayers);
    
    GroundedRemember -= Time.deltaTime;
    if (Grounded)
    {
      GroundedRemember = GroundedRememberTime;
    }

    JumpPressedRemember -= Time.deltaTime; 
  
    if ((JumpPressedRemember > 0)) {
      TryJump();
    }

    rb.velocity = new Vector2(rb.velocity.x, jumpForce);
    
     float HorizontalVelocity = rb.velocity.x;
      HorizontalVelocity += moveInput.x;
          
        if (Mathf.Abs(moveInput.x) < 0.01f)
            HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenStopping, Time.deltaTime * 10f);
           else if (Mathf.Sign(moveInput.x) != Mathf.Sign(HorizontalVelocity))
           HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenTurning, Time.deltaTime * 10f);
        else
            HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingBasic, Time.deltaTime * 10f);

        rb.velocity = new Vector2(HorizontalVelocity, rb.velocity.y);    
  }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用UnityEngine.InputSystem;
公共类PlayerController:MonoBehavior、PlayerInputActions.IPlayerActions
{
私人玩家电脑操作控制;
[SerializeField]LayerMask地面层;
私有刚体2d rb;
私人动画师;
私有bool-facingRight=true;
私有向量2移动输入;
[Field]私人浮动跳线部队;
float jumpressedremember=0;
[SerializeField]浮动跳线PressedRememberTime=0.2f;
浮动接地数字=0;
[SerializeField]float GroundedRememberTime=0.25f;
[SerializeField]浮点水平加速度=1;
[SerializeField][Range(0,1)]浮点水平阻尼基本=0.5f;
[SerializeField][Range(0,1)]浮动水平阻尼(当停止=0.5f时);
[SerializeField][Range(0,1)]旋转时浮动水平阻尼=0.5f;
[field][Range(0,1)]浮动跳线高度=0.5f;
私人空间
{
控件=新的PlayerInputActions();
controls.Player.SetCallbacks(this);
}
void Start()
{
rb=GetComponent();
anim=GetComponent();
}
void PlayerInputActions.IPlayerActions.OnMove(InputAction.CallbackContext上下文)
{
moveInput=context.ReadValue();
}
无效跳转(){
rb.AddForce(矢量2.up*跳跃力,ForceMode2D.Force);
GroundedRemember=0;
JumpPressedMember=0;
}
bool TryJump(){
如果(GroundedRemember>0){
跳跃();
返回true;
}否则{
JumpPressedMember=JumpPressedMemberTime;
返回false;
}
}
void PlayerInputActions.IPlayerActions.OnJump(InputAction.CallbackContext上下文)
{
jumpForce=context.ReadValue();
切换(上下文阶段){
案例输入阶段。执行:
TryJump();
打破
}
}
void FixedUpdate()
{
if(facingRight==false&&moveInput.x>0){
翻转();
}else if(facingRight==true&&moveInput.x<0){
翻转();
}
}
void Flip(){
facingRight=!facingRight;
Vector3 Scaler=transform.localScale;
Scaler.x*=-1;
transform.localScale=Scaler;
}  
void OnEnable()
{
控件。Enable();
}
无效可禁用()
{
控件。禁用();
}
无效更新()
{
Vector2 GroundedBoxCheckPosition=(Vector2)transform.position+新Vector2(0,-0.01f);
Vector2 GroundedBoxCheckScale=(Vector2)transform.localScale+新Vector2(-0.02f,0);
bool Grounded=Physics2D.overlaybox(GroundedBoxCheckPosition,transform.localScale,0,groundLayers);
GroundedRemember-=Time.deltaTime;
如果(接地)
{
GroundedRemember=GroundedRememberTime;
}
JumpPressedMember-=Time.deltaTime;
如果((JumpPressedMember>0)){
TryJump();
}
rb.velocity=新矢量2(rb.velocity.x,跳跃力);
浮动水平速度=rb.velocity.x;
水平速度+=moveInput.x;
如果(数学绝对值(moveInput.x)<0.01f)
水平速度*=数学功率(1f-停止时的水平阻尼,时间增量*10f);
else如果(数学符号(moveInput.x)!=数学符号(水平速度))
水平速度*=数学功率(1f-转动时的水平阻尼,时间增量*10f);
其他的
水平速度*=数学功率(1f-水平阻尼基本,时间增量*10f);
rb.velocity=新矢量2(水平速度,rb.velocity.y);
}
}

如果您知道玩家跳跃的幅度,那么可以尝试为下一次跳跃增加延迟

如果您知道如何使用协同程序,可以使用
Invoke()
函数


但我仍然建议使用地面检查,因为它很实用,而且更简单,我看不出你为什么不使用它。

谢谢你的回答。如果我快速按下跳跃按钮,玩家可以永远跳跃。如您所见,为了进行实地检查,我附加了一个指向我在问题中使用的教程的链接。如果你看到了,你会发现我为什么要用这个。但如果我想快速解释,我必须说我想使用它,因为它使游戏更具响应性。地面检查检查你是否在地面上,如果在地面上,你可以跳,但是如果你不在地面上,但是离地面很近,比如厘米,你就不能跳,这就是我的问题。