[英]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.