Godot C#二段跳实现异常求助:角色无法完成二段跳
Godot C# 二段跳失效问题排查与修复
核心问题分析
- 跳跃输入检测错误:用
Input.IsActionPressed会在按住跳跃键的每一帧都触发跳跃逻辑,导致_jump_counter瞬间达到上限,直接耗尽二段跳机会。应该用Input.IsActionJustPressed只响应按键按下的单次事件。 - Velocity逻辑混乱:代码中多次重复赋值
velocity = Velocity,动画处理部分还错误修改了velocity的X分量(归一化后乘以_runSpeed会覆盖之前的速度设置),重力添加的位置也不符合物理逻辑顺序。 - 跳跃状态触发逻辑模糊:原代码的跳跃判断没有区分落地跳和二段跳的场景,加上输入检测的问题,玩家还没触发二段跳,计数器就已经被耗尽。
修复后的完整代码
using Godot; public partial class Player : CharacterBody2D { private float _runSpeed = 750; private float _jumpSpeed = -1000; private float _gravity = 2500; private int _jumpCounter = 0; private int _extraJumps = 1; // 允许1次额外跳跃,总跳跃次数为2次 public override void _PhysicsProcess(double delta) { var velocity = Velocity; // 先处理重力:只有不在地面时才施加重力 if (!IsOnFloor()) { velocity.Y += _gravity * (float)delta; } // 重置X轴速度,避免残留移动惯性 velocity.X = 0; // 获取输入状态 var right = Input.IsActionPressed("move_right"); var left = Input.IsActionPressed("move_left"); var jump = Input.IsActionJustPressed("move_jump"); // 改为检测单次按键按下 // 处理左右移动 if (right) { velocity.X += _runSpeed; } if (left) { velocity.X -= _runSpeed; } // 处理跳跃逻辑 if (jump) { // 落地状态下直接跳,重置跳跃计数器 if (IsOnFloor()) { velocity.Y = _jumpSpeed; _jumpCounter = 0; } // 非落地状态下,还有额外跳跃次数时触发二段跳 else if (_jumpCounter < _extraJumps) { velocity.Y = _jumpSpeed; _jumpCounter++; GD.Print($"已使用跳跃次数: {_jumpCounter + 1}"); // 总次数=初始1次+额外次数 } } // 落地时重置跳跃计数器,确保下次能正常起跳 if (IsOnFloor()) { _jumpCounter = 0; } // 动画处理 var animatedSprite2D = GetNode<AnimatedSprite2D>("Sprite2D"); if (Mathf.Abs(velocity.X) > 0) { animatedSprite2D.Play("walking"); animatedSprite2D.FlipH = velocity.X < 0; } else { animatedSprite2D.Stop(); } // 更新速度并执行移动 Velocity = velocity; MoveAndSlide(); } }
关键修复点说明
- 输入检测修正:替换
Input.IsActionPressed为Input.IsActionJustPressed,确保每次按键只触发一次跳跃,不会快速耗尽二段跳次数。 - 重力逻辑调整:把重力施加逻辑提前,且仅在非落地状态生效,符合真实物理下落逻辑。
- Velocity流程梳理:统一Velocity的修改顺序,避免重复赋值和错误覆盖,确保移动、跳跃、重力的逻辑优先级正确。
- 跳跃逻辑拆分:明确区分落地跳和二段跳的触发条件,让逻辑更清晰,同时添加调试打印方便排查问题。
内容的提问来源于stack exchange,提问作者jwhatrucoding
相关产品推荐
相关产品推荐

