【问题标题】:My character is doing an unexpected 3rd jump in Unity2D我的角色在 Unity2D 中进行了意想不到的第三次跳跃
【发布时间】:2016-01-27 00:40:58
【问题描述】:

你好!

我目前正在开发 Unity 引擎中的 2D 平台游戏,我在其中创建了一个可以进行双跳的角色。
一开始一切都很好,但我现在意识到有一个破坏游戏的错误使他能够进行第三次跳跃(出于某种原因)。我不能为了它找出问题所在。

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();
    }
}
}  

感谢所有帮助!

【问题讨论】:

  • 只是作为一个测试,尝试将maxjumps设置为1。看看你是否可以获得2次跳跃。这可能是操作顺序问题,在按下跳转后但在与地面保持接触之前,您会得到 isGrounded = true。
  • 你能在它运行时调试或打印一些信息吗?我很好奇isGrounded 是否会导致任何问题并过早重置currentJumps
  • 我已经测试了理论,问题确实是基于 currentJumps 被过早重置!

标签: c# unity3d 2d controllers unity5


【解决方案1】:

void JumpLogic(),你在打电话

currentJumps++;
CheckGroundCollision();

第一次按下跳转键时,currentJumps 变为 1(currentJumps++),但随后isGrounded 再次变为真(因为当前帧中尚未应用物理,角色仍然触摸地面图层蒙版)。所以下次调用JumpLogic() 时,currentJumps 在运行跳转键代码之前会因为if (isGrounded) currentJumps = 0; 而重置为零。

我建议删除void JumpLogic() 内部对CheckGroundCollision(); 的最后一次调用。 无论如何,它们都在 Update() 内部调用,其顺序看起来可行。

希望对你有帮助!

更新: 我刚刚注意到您还在Update() 本身内部第二次调用CheckGroundCollision();。那也将重置跳转变量。

尝试修改您的原始代码:

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
    }
}

希望对你有帮助!

【讨论】:

  • 我尝试删除它,但问题仍然存在。我最近确认问题是我的 currentJumps 过早重置。
  • 尝试更改 CheckGroundCollision();JumpLogic(); 在 Update... 中的顺序以及我上面建议的更改。
  • 这让事情变得更糟了。现在,三级跳的工作方式就像双级跳一样。 (他总能出三分)
  • @riddarn97 检查我更新的答案。我意识到您正在做某事,并想建议代码编辑。
  • 那也没用。我不知道我的代码出了什么问题……这种行为出乎意料,几乎是滑稽的。
【解决方案2】:

我建议让对撞机向玩家控制器指示 isGrounded 的状态,而不是查询对撞机。例如,继续 andeart's 建议,您的代码可能看起来更像以下内容

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++;
    }
}

请参阅Collider2D.IsTouchingLayers,尤其是底部段落,该段落暗示 IsTouchingLayers 方法可能无法针对碰撞器给出最准确的结果。

【讨论】:

    猜你喜欢
    • 2023-01-28
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    相关资源
    最近更新 更多