[英]My character is doing an unexpected 3rd jump in Unity2D
你好!
我目前正在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();
}
}
}
感謝所有幫助!
在void JumpLogic()
,您正在調用
currentJumps++;
CheckGroundCollision();
第一次按下跳轉鍵時, currentJumps
變為1(currentJumps ++),然后isGrounded
再次變為true(因為在當前幀中尚未應用物理方法,並且角色仍在接觸地面圖層蒙版)。 因此,下次調用JumpLogic()
,由於if (isGrounded) currentJumps = 0;
因此currentJumps
重置為零if (isGrounded) currentJumps = 0;
在運行跳轉鍵代碼之前。
我建議刪除對CheckGroundCollision();
的最后一次調用CheckGroundCollision();
在void JumpLogic()
內部。 無論如何,它們都在Update()
內部被調用,其順序似乎可行。
希望對您有所幫助!
更新:我剛剛注意到您還調用CheckGroundCollision();
第二次在Update()
本身內部。 那也將重置跳轉變量。
嘗試對原始代碼進行以下修改:
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
}
}
希望對您有所幫助!
我建議讓對撞機指示播放器控制器isGrounded的狀態,而不要查詢對撞機。 例如,繼續執行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++;
}
}
請參閱Collider2D.IsTouchingLayers,尤其是最下面的段落,它暗示着IsTouchingLayers方法相對於對撞機可能無法提供最准確的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.