class_name PlayerGroundState extends LimboState ## 地面叶子状态的公共基类(Idle / Walk / Sprint / Crouch / Sneak 共用)。 ## ## 每帧先统一判定「环境事实」,之后才轮到 _think() 里各状态自己的输入转换: ## 1. 跳跃缓冲成立(try_jump 当场起跳)→ 转空中(vy > 0 → Jump); ## 2. 脚下没地板(踏空)→ 转空中(Fall)。 ## 这两层判定放在**叶子**而不是父机:父机 _update 先于子状态执行, ## 若在父机里 dispatch,转换后父机本轮还会继续调(已被退出的)旧子状态, ## 存在「旧状态在已退出的机器里再次 dispatch」的顺序陷阱;叶子自己判、 ## dispatch 后立即 return,则没有这个窗口。 ## ## is_on_floor() 反映的是上一帧 move_and_slide() 的结果 —— ## 与推进的更新节奏一致,不引入额外的检测延迟。 func _update(delta: float) -> void: var player := get_agent() as Player if player == null: return if player.motor.try_jump(): dispatch(&"airborne") return if not player.is_on_floor(): dispatch(&"airborne") return _think(delta) ## 各状态自己的输入转换。要不要 dispatch 事件、往哪转,由具体状态决定 ## (转换表注册在 grounded.gd 的 _setup 里)。 func _think(_delta: float) -> void: pass