简体   繁体   English

我的角色在Unity2D中执行了意外的第三跳

[英]My character is doing an unexpected 3rd jump in Unity2D

Hello! 你好!

I am currently working on a 2D plattformer game in the Unity engine, where I have created a character that can preform a doubblejump. 我目前正在Unity引擎中开发2D平台游戏,在那里我创建了可以进行双倍跳跃的角色。
It all worked pretty good in the beginning, but I have now realized that there is a game breaking bug that makes him able to preform a third jump (for some reason). 在一开始的时候一切都很好,但是我现在已经意识到,存在一个打破游戏规则的错误,使他能够执行第三跳(出于某种原因)。 And I can't for the sake of it figure out what the problem is. 而且我不能为了找出问题所在。

PlayerController.cs PlayerController.cs

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour {

    /*
    TODO: Find out why the character ocationally
    gets 3 jumps instead of 2.
    I think it's the "isGrounded" that returns
    a false posetive.
    */

[Header("Ground Recognition")]
public BoxCollider2D groundCollider;
public LayerMask groundAbles;

[Header("Audio")]
public GameObject jumpSound = null;

[Header("Visual")]
public GameObject jumpEffect = null;


float speed = 5f;
int maxJumps = 2;
int currentJumps = 0;

bool isGrounded = false;
float boundsLength = 0;

Vector3 movement;
// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update() {
    CheckGroundCollision();
    JumpLogic();

    movement = new Vector3(Input.GetAxis("Horizontal") * speed, 0, 0);
    movement *= Time.deltaTime;
    transform.position += movement;

    CheckGroundCollision();
}

void CheckGroundCollision()
{
    isGrounded = groundCollider.IsTouchingLayers(groundAbles);
}

void JumpLogic()
{

    if (isGrounded)
        currentJumps = 0;

    if (Input.GetButtonDown("Jump") && currentJumps < maxJumps)
    {
        GameObject newJumpSound = (GameObject)GameObject.Instantiate(jumpSound, (Vector2)transform.position, transform.rotation);
        GameObject newJumpEffect = (GameObject)GameObject.Instantiate(jumpEffect, (Vector2)transform.position - new Vector2(0, 0.25f), transform.rotation);
        GameObject.Destroy(newJumpEffect, 0.2f);
        GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, 0);
        GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 10), ForceMode2D.Impulse);
        currentJumps++;
        CheckGroundCollision();
    }
}
}  

All help is appreciated! 感谢所有帮助!

In void JumpLogic() , you're calling void JumpLogic() ,您正在调用

currentJumps++;
CheckGroundCollision();

The very first time you press the jump-key, currentJumps becomes 1 (currentJumps++), but then isGrounded becomes true again (because the physics has not been applied yet in the current frame, and the character is still touching the ground layermask). 第一次按下跳转键时, currentJumps变为1(currentJumps ++),然后isGrounded再次变为true(因为在当前帧中尚未应用物理方法,并且角色仍在接触地面图层蒙版)。 So the next time JumpLogic() is called, currentJumps is reset to zero because of if (isGrounded) currentJumps = 0; 因此,下次调用JumpLogic() ,由于if (isGrounded) currentJumps = 0;因此currentJumps重置为零if (isGrounded) currentJumps = 0; before running the jump-key code. 在运行跳转键代码之前。

I suggest removing the last call to CheckGroundCollision(); 我建议删除对CheckGroundCollision();的最后一次调用CheckGroundCollision(); inside of void JumpLogic() . void JumpLogic()内部。 They are both called inside Update() anyway, in an order that looks like it would work. 无论如何,它们都在Update()内部被调用,其顺序似乎可行。

I hope that helps! 希望对您有所帮助!

UPDATE: I just noticed you're also calling CheckGroundCollision(); 更新:我刚刚注意到您还调用CheckGroundCollision(); a second time inside Update() itself. 第二次在Update()本身内部。 That would be resetting the jump variable too. 那也将重置跳转变量。

Try this modification of your original code: 尝试对原始代码进行以下修改:

void Update() {
    CheckGroundCollision();
    JumpLogic();

    movement = new Vector3(Input.GetAxis("Horizontal") * speed, 0, 0);
    movement *= Time.deltaTime;
    transform.position += movement;

    //** NOTE- REMOVED THIS LINE
}

...

void JumpLogic()
{

    if (isGrounded)
        currentJumps = 0;

    if (Input.GetButtonDown("Jump") && currentJumps < maxJumps)
    {
        GameObject newJumpSound = (GameObject)GameObject.Instantiate(jumpSound, (Vector2)transform.position, transform.rotation);
        GameObject newJumpEffect = (GameObject)GameObject.Instantiate(jumpEffect, (Vector2)transform.position - new Vector2(0, 0.25f), transform.rotation);
        GameObject.Destroy(newJumpEffect, 0.2f);
        GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, 0);
        GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 10), ForceMode2D.Impulse);
        currentJumps++;

        //** NOTE- REMOVED THIS LINE
    }
}

I hope that helps! 希望对您有所帮助!

I would suggest letting the collider dictate to the player controller the state of isGrounded rather than querying the collider. 我建议让对撞机指示播放器控制器isGrounded的状态,而不要查询对撞机。 For example, continuing on andeart's suggestions, your code could look more like the following 例如,继续执行andeart的建议,您的代码可能更像以下内容

void Update() {
    JumpLogic();

    movement = new Vector3(Input.GetAxis("Horizontal") * speed, 0, 0);
    movement *= Time.deltaTime;
    transform.position += movement;
}

//let the collider indicate to the player controller when
//a collision occurs, then determine if this collision is relevant
void OnCollisionEnter2D(Collision2D coll) {
    if(coll.IsTouchingLayers(groundAbles))    
      isGrounded = true;

    // or do some other check using layers or tags ....
}

void JumpLogic()
{
    if (isGrounded)
        currentJumps = 0;

    if (Input.GetButtonDown("Jump") && currentJumps < maxJumps)
    {
        GameObject newJumpSound = (GameObject)GameObject.Instantiate(jumpSound, (Vector2)transform.position, transform.rotation);
        GameObject newJumpEffect = (GameObject)GameObject.Instantiate(jumpEffect, (Vector2)transform.position - new Vector2(0, 0.25f), transform.rotation);
        GameObject.Destroy(newJumpEffect, 0.2f);
        GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, 0);
        GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 10), ForceMode2D.Impulse);
        currentJumps++;
    }
}

See Collider2D.IsTouchingLayers particularly the bottom paragraph which implies that the IsTouchingLayers method may not give the most acurate result with respect to the collider. 请参阅Collider2D.IsTouchingLayers,尤其是最下面的段落,它暗示着IsTouchingLayers方法相对于对撞机可能无法提供最准确的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM