平台游戏L型地形角色跳跃异常问题求助
问题描述
我正在开发一款2D平台游戏,角色处于L型地形(下方和侧边各有一个方块)时无法正常跳跃,表现得像是与上方方块发生了碰撞。操控角色向平台移动并尝试跳跃时,动作卡顿,角色几乎立刻落回地面。
无法跳跃场景示意图:
角色移动核心代码如下:
void Update() { //Movimiento if (!isCrouching) { rb.velocity = new Vector2(Input.GetAxisRaw("Horizontal") * spd, rb.velocity.y); anim.SetFloat("speed", Mathf.Abs(rb.velocity.x)); rb.drag = 0; } else { if (Input.GetAxisRaw("Horizontal") != 0) { rb.drag = crouchFriction; } else { rb.drag = 0; rb.velocity = new Vector2(0, rb.velocity.y); } } //Flip Flip(); //GroundCheck GroundCheck(); //Saltar if (Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.W)) { if (!isCrouching) { jumpBuffCount = jumpBuffTime; } } else { jumpBuffCount -= Time.deltaTime; } if (jumpBuffCount > 0) { if (coyoteTimeCount > 0) { rb.velocity = new Vector2(rb.velocity.x, jumpForce); jumpBuffCount = 0; } } if ((Input.GetKeyUp(KeyCode.UpArrow) || Input.GetKeyUp(KeyCode.W)) && isGrounded) { coyoteTimeCount = 0; } if (!isGrounded) { if (transform.parent == null || transform.parent != null && !transform.parent.CompareTag("FallingPlatform")) { if (rb.velocity.y > 0.1f) { anim.SetBool("isJumping", true); anim.SetBool("isFalling", false); } else { anim.SetBool("isJumping", false); anim.SetBool("isFalling", true); } } } else { anim.SetBool("isJumping", false); anim.SetBool("isFalling", false); } //Agacharse Crouch(); anim.SetBool("isCrouching", isCrouching); } private void GroundCheck() { Collider2D hit = Physics2D.OverlapBox(new Vector2(transform.position.x, transform.position.y - 0.5f), new Vector2(0.96f, 0.06f), 0, colision); isGrounded = hit; if (isGrounded) { coyoteTimeCount = coyoteTime; } else { coyoteTimeCount -= Time.deltaTime; } }
已尝试的操作:
- 给角色和Tilemap添加无摩擦的Physics Material 2D
- 调整groundcheck范围使其小于碰撞体,避免检测到墙壁
- 测试其他场景,问题仅在L型地形出现
解决方案
1. 修复跳跃时的卡墙冲突
当前跳跃逻辑直接设置垂直速度,但角色贴着L型侧边方块时,水平碰撞会导致Rigidbody2D的水平速度被强制清零,甚至产生向上的碰撞反馈抵消跳跃力。修改跳跃逻辑,在跳跃瞬间给侧面碰撞一个微小的推开力:
if (jumpBuffCount > 0 && coyoteTimeCount > 0) { float horizontalInput = Input.GetAxisRaw("Horizontal"); // 检测角色侧面是否有碰撞 Collider2D sideHit = Physics2D.OverlapBox( new Vector2(transform.position.x + (horizontalInput * 0.5f), transform.position.y), new Vector2(0.06f, 0.96f), 0, colision ); if (sideHit != null) { // 给反向小力,避免卡墙 rb.AddForce(new Vector2(-horizontalInput * 5f, 0), ForceMode2D.Impulse); } rb.velocity = new Vector2(rb.velocity.x, jumpForce); jumpBuffCount = 0; }
2. 优化GroundCheck的检测精度
当前GroundCheck的OverlapBox宽度接近角色碰撞体,在L型地形可能同时检测到地面和侧边墙壁,导致isGrounded误判。修改为只检测角色正下方区域:
private void GroundCheck() { // 缩小检测宽度,只覆盖角色中心下方 Collider2D hit = Physics2D.OverlapBox( new Vector2(transform.position.x, transform.position.y - 0.5f), new Vector2(0.6f, 0.06f), 0, colision ); // 额外判断:确保碰撞体在角色下方 isGrounded = hit != null && hit.bounds.max.y < transform.position.y; if (isGrounded) { coyoteTimeCount = coyoteTime; } else { coyoteTimeCount -= Time.deltaTime; } }
3. 调整角色碰撞体参数
如果角色使用BoxCollider2D,尝试:
- 将碰撞体宽度缩小10%,减少和侧边方块的重叠概率
- 把碰撞体y轴锚点稍微向上偏移,避免底部碰撞体过度贴合地形边缘
4. 优化Rigidbody2D碰撞设置
在Rigidbody2D组件中:
- 将
Collision Detection设置为Continuous,减少高速移动时的碰撞穿透 - 勾选
Use Full Kinematic Contacts,提升碰撞检测的准确性
5. 调试碰撞状态
添加调试代码,查看跳跃瞬间的碰撞详情:
void Update() { // ... 原有代码 ... // 按F1查看碰撞信息 if (Input.GetKeyDown(KeyCode.F1)) { Debug.Log("Is Grounded: " + isGrounded); Collider2D[] hits = Physics2D.OverlapBoxAll(transform.position, GetComponent<BoxCollider2D>().size, 0, colision); foreach (var hit in hits) { Debug.Log("碰撞对象: " + hit.gameObject.name + " | 位置: " + hit.transform.position); } } }
通过调试信息确认是否真的和上方方块发生碰撞,或者有其他碰撞体干扰。
内容的提问来源于stack exchange,提问作者Marcos T
相关产品推荐
相关产品推荐

