嗨,我怎样才能阻止我的 2D 角色停止在空中跳跃?

Hi, how can i stop my 2D character to stop jumping in the air?

当我按下跳跃按钮时,他总是会跳跃。我希望你能帮助我。这是我的第一场比赛,所以我不太了解。这是我的代码:

Rigidbody2D rb;
float dirX;
float jumpForce = 300f;
private bool canJump = false;
private bool hasSwitchedLayers = false;
public Transform Teleport1;
private Vector3 startPos;

void Start()
{
    startPos = new Vector3(-10, 1.5f, 0);
    rb = GetComponent<Rigidbody2D>();  
}

void Update()
{
    dirX = CrossPlatformInputManager.GetAxis("Horizontal");
    rb.velocity = new Vector2(dirX * 10, rb.velocity.y);

    if (CrossPlatformInputManager.GetButtonDown("Jump") )
    {
        rb.AddForce(new Vector2(rb.velocity.x, jumpForce), ForceMode2D.Force);  
    }
}

防止游戏对象在空中跳跃的方法有多种,但我认为这是最简单的方法。首先,确保你的游戏对象有一个附加到它的对撞机。如果是这样,您将不得不创建一个响应所有碰撞的方法,并且您还必须引入一个名为 isJumping:

的新变量
bool isJumping = false;
void OnCollisionEnter2D(Collision2D col) //this method responds to all collisions
{
    jumping = false;
}
if (CrossPlatformInputManager.GetButtonDown("Jump") && !jumping) //making sure that the game object is not already jumping
{
    rb.AddForce(new Vector2(rb.velocity.x, jumpForce), ForceMode2D.Force);
    jumping = true;
}

虽然这个解决方案可能并不完美,并且您可能会遇到错误,例如您的游戏对象在与 walls/obstacles 半空中碰撞时能够跳跃,但这是我能想到的最简单的解决方案。而且,为了尽量避免该错误,请确保为此使用的对撞机位于游戏对象的底部(以便它只有在落地时才能跳跃)。另外,如果您想了解有关 OnCollisionEnter2D 方法的更多信息,请查看 Unity 文档中的 OnCollisionEnter2D(Collision2D)

Add an isGrounded boolean into your script. Add a check for isGrounded in your jump if statement like this if(CrossPlatformInputManager.GetButtonDown("Jump") && isGrounded){}. However, you will have to add a statement to check if the player is actual on the ground. You could do this in multiple ways.

You could use a simple short raycast to detect if you are on the ground. isGrounded = Physics2D.Raycast(transform.position, Vector3.down, distToGround + 0.2), note that distToGround = collider.bounds.extents.y. This will create a raycast, that will travel down from the player(the distance it will travel would be from the player's collision pivot to its collision edge on the bottom plus a bit more just in case you are on a slope, etc.). It will return true if it hits any object in its path. This method would require it to be in the update method. However, you could also just add it into isGrounded itself by doing

bool isGrounded(){
    return Physics2D.Raycast(transform.position, Vector3.down, distToGround + 0.2);
}
void Update(){
    if(isGrounded() && .......){}
}

If your character has a character controller, you can also just use a simple if(CharacterController.isGrounded) statement

Another method you could use is to add a small collision sphere/box under your player's feet. This could be done in two ways. 1st, you could just have the player detect collisions, and check if that is the ground,

private bool IsGrounded;
void OnCollisionEnter2D(Collision2D c){
    if(c.tag == "ground"){
        isGrounded = true;
    }
}
void OnCollisionExit2D(Collision2D c){
    if(c.tag == "ground"){
        isGrounded = false;
    }
}

2nd(more complicated), you could add an empty game object in the editor with an attached collision box/sphere(with isTrigger == true) and a script. This gameobject would be a child of the player, and it should be near the players feet. In its script, you could add a static variable public static bool isPlayerGrounded, and then a simple OnTriggerEnter2D and OnTriggerExit2D functions, with a check if the object they are triggered by is ground by using tags.

public static bool IsPlayerGrounded;
void OnTriggerEnter2D(Collider2D c){
    if(c.tag == "ground"){
        IsPlayerGrounded = true;
    }
}
void OnTriggerExit2D(Collider2D c){
    if(c.tag == "ground"){
        IsPlayerGrounded = false;
    }
}

Then, you can check if the player is grounded in the player script

private Isgrounded;
void Update(){
    Isgrounded = NameofOtherScript.IsPlayerGrounded;
}