Unity 2D平台跳跃异常:玩家每隔几次跳跃高度过高问题排查
2D平台游戏超高跳跃异常问题排查与修复
问题描述
我正在开发一款2D平台游戏,玩家多数时候跳跃高度正常,但每隔几次会出现超高跳跃的异常情况。怀疑是已停用平台的影响,但不知道如何修复。
问题代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class Movement : MonoBehaviour { public float speedright = 30; public GameObject player; public Rigidbody2D rb; public float speedleft = -100; public Text e; Scene currentScene; string sceneName; public float jumpheight = 115; public Talking script; bool isJumping; public Text h; public float hp = 100; public GameObject playerbody; public Animator anim; public Rigidbody2D bg; public float bgspeedright = -1.5f; public float bgspeedleft = 1.5f; bool cjump = false; public float Health = 100; public float Count; public string Scene2; void Start() { Count = 0; Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; rb.constraints = RigidbodyConstraints2D.FreezeRotation; script.CanMove = 1; } private void OnTriggerStay2D(Collider2D collider) { if (sceneName == "Bedroom"){ e.text = "E To Interact"; e.gameObject.SetActive(true); if(Input.GetKeyDown("e")) { SceneManager.LoadScene("Hallway"); } } } void Update() { Health = script.Health; bgspeedright = -0.9f; bgspeedleft = 0.9f; if (sceneName == "Butterland") { h.text = $"Health: {Health}"; } jumpheight = 80; if (Health <= 1) { Debug.Log("DIE"); SceneManager.LoadScene("Death"); } if (Count == 5 || Count > 5) { SceneManager.LoadScene("You Cheater!"); } } private void OnCollisionEnter2D(Collision2D other) { if (other.gameObject.CompareTag("Cheater Detection")) { InvokeRepeating("Counter", 1, 1); } if (other.gameObject.CompareTag("Floor")) { isJumping = false; } if (other.gameObject.CompareTag("Platform")) { isJumping = false; } if (other.gameObject.CompareTag("Floor") && script.floordanger == true) { Health = 0; } } private void OnCollisionExit2D(Collision2D other) { CancelInvoke("Counter"); } void FixedUpdate() { if (script.CanMove == 1) { if (Input.GetKey("d")) { rb.velocity = new Vector2(speedright, rb.velocity.y); rb.transform.eulerAngles = new Vector3(0, 0, 0); bg.velocity = new Vector2(bgspeedright, bg.velocity.y); } if (Input.GetKey("a")) { rb.velocity = new Vector2(speedleft, rb.velocity.y); bg.velocity = new Vector2(bgspeedleft, bg.velocity.y); rb.transform.eulerAngles = new Vector3(0, 180, 0); } if (!Input.GetKey("a") && !Input.GetKey("d")) { bg.velocity = new Vector2(0, bg.velocity.y); } if (Input.GetKey("a") || Input.GetKey("d")) { anim.SetBool("IsWalking", true); } if (Input.GetKeyUp("d")) { anim.SetBool("IsWalking_Right", false); } if (Input.GetKeyUp("a")) { anim.SetBool("IsWalking", false); } if (Input.GetKeyDown(KeyCode.Space) && isJumping == false) { rb.AddForce(Vector2.up * jumpheight, ForceMode2D.Impulse); cjump = true; if(cjump == true) { Invoke("CJump", 0.012f); } } if (Input.GetKeyDown(KeyCode.LeftShift)) { speedleft = -15; speedright = 15; } if (!Input.GetKeyDown(KeyCode.LeftShift)) { speedleft = -10; speedright = 10; } } } void CJump() { isJumping = true; cjump = false; } void Counter() { Count = Count + 1; } }
问题根源分析
- 跳跃状态延迟标记漏洞:当前通过
Invoke("CJump", 0.012f)延迟设置isJumping = true,这12毫秒内如果碰撞检测异常或误触输入,会重复触发rb.AddForce,叠加跳跃力导致超高跳。 - 无效碰撞未过滤:已停用的平台如果仍能触发
OnCollisionEnter2D,会错误将isJumping重置为false,让玩家可以再次跳跃。 - 移动速度逻辑错误:
FixedUpdate中用!Input.GetKeyDown(KeyCode.LeftShift)判断松开Shift,会每帧都重置速度,导致加速状态不稳定。
修复方案
1. 同步标记跳跃状态,移除延迟逻辑
删除cjump变量、CJump()方法和Invoke调用,按下空格时立即标记跳跃状态:
if (Input.GetKeyDown(KeyCode.Space) && isJumping == false) { rb.AddForce(Vector2.up * jumpheight, ForceMode2D.Impulse); isJumping = true; // 直接标记为跳跃中,避免重复触发 }
2. 过滤已停用平台的碰撞触发
在OnCollisionEnter2D中添加平台激活状态判断,仅允许激活的平台重置跳跃状态:
if (other.gameObject.CompareTag("Platform") && other.gameObject.activeSelf) { isJumping = false; }
3. 修正移动速度的判定逻辑
将Shift松开的判断改为Input.GetKeyUp,避免每帧重置速度:
if (Input.GetKey(KeyCode.LeftShift)) { speedleft = -15; speedright = 15; } if (Input.GetKeyUp(KeyCode.LeftShift)) { speedleft = -10; speedright = 10; }
4. 可选:限制垂直速度上限
为防止意外力叠加,添加垂直速度限制:
// 在FixedUpdate末尾添加 if (rb.velocity.y > 12f) // 根据游戏需求调整数值 { rb.velocity = new Vector2(rb.velocity.x, 12f); }
内容的提问来源于stack exchange,提问作者user22411435
相关产品推荐
相关产品推荐

