Files
rpg_start/Study_One/Q&A.md

6.0 KiB
Raw Blame History

Q&A

学习过程中遇到的问题记录


Q1为什么保留 rb.linearVelocity.y 不会导致 Player 上下移动,而改变 x 就会左右移动?

关键理解

rb.linearVelocity 每一帧都被完整重新赋值X 和 Y 的来源不同决定了它们的行为不同。

X 轴:由输入主动控制

rb.linearVelocity = new Vector2(xInput * moveSpeed, rb.linearVelocity.y);
//                     ^^^^^^^^^^^^^^^^
//                     这部分的数值由你决定
操作 xInput velocity.x 效果
按 A / ← -1 -3.5 向左移动
松开 0 0 停止
按 D / → 1 3.5 向右移动

每次赋值X 都被设为输入决定的明确值,所以会立刻产生/停止移动。

Y 轴:物理系统已经在运行

rb.linearVelocity.y 不是空的,它已经是物理引擎当前帧算好的结果:

状态 velocity.y 实际值 保留后效果
站地上 ≈ 0 不动(地面碰撞把 y 锁为 0
下落中 < 0重力累加 继续下落
跳起后 > 0 → 逐渐减小 上升 → 减速 → 下落

保留 Y 的本质是 "不去干涉" 物理系统对垂直运动的控制,而不是"主动让角色上下动"。

反例:写死 Y 会怎样?

rb.linearVelocity = new Vector2(xInput * moveSpeed, 0);  // ❌
  • 重力被清零 → 角色不会下落,飘在空中
  • 跳跃被清零 → 跳不起来
  • 地面碰撞结果被覆盖 → 可能会卡进地面

一句话总结

X 轴 velocity 是你主动赋值来命令移动Y 轴 velocity 是物理系统正在运行的结果,保留它只是不去搞破坏。


2026-05-23

Q2跳跃时直接覆盖 Y 为 jumpForce,和之前说的"保留 Y"不矛盾吗?为什么不用 y + jumpForce

问题背景

之前的 Q&A 说"保留 rb.linearVelocity.y 不去干涉物理系统",但跳跃代码却直接覆盖:

// 平时移动:保留 Y不去干扰物理
rb.linearVelocity = new Vector2(xInput * moveSpeed, rb.linearVelocity.y);

// 跳跃时:覆盖 Y
rb.linearVelocity = new Vector2(rb.linearVelocity.x, jumpForce);

直觉上会觉得应该写成 rb.linearVelocity.y + jumpForce 才对。

核心解答

场景不同,原则不同:

场景 对 Y 的操作 意图
左右移动 保留 Y 不管物理系统的事
跳跃 覆盖 Y = jumpForce 主动干预,跳跃本身就是这个干预

平时保留 Y 是因为"不需要管 Y",跳跃覆盖 Y 是因为"现在就要动 Y"。

为什么用 = jumpForce 而不是 += jumpForce

站在平地时 velocity.y ≈ 0,两者结果一样。但在以下情况加法会出问题:

场景 velocity.y 当前值 = jumpForce += jumpForce 哪个合理
平地站着 ≈ 0 = 8 = 8 一样
在上升平台上跳 > 0如 +3 = 8 = 11 异常高 =
下落中误触跳跃 < 0如 -5 = 8 = 3 跳不起来 =
  • = jumpForce — 每次跳跃高度一致,可预测
  • += jumpForce — 跳跃高度受当前 Y 速度影响,结果不稳定

总结

保留 Y = 不想管物理的事 覆盖 Y = 正在主动做跳跃这件事= 保证每次跳跃可预测,用 += 反而会让跳跃高度飘忽不定


Q3二段跳可以从哪些方面入手设计

前提

第九次更新已经实现了接地检测(isGrounded),跳跃被限制为"只有在地上才能跳"。在此基础上扩展二段跳,需要考虑以下几个维度:

1. 核心机制 —— 如何判断"能不能跳"

计数器方案(推荐,可扩展性强):

jumpCount = 允许的跳跃次数(例如 2
remainingJumps = 当前剩余次数

想跳时:
  1. 检查 remainingJumps > 0
  2. 是 → 跳remainingJumps--
  3. 否 → 不跳

落地时:
  重置 remainingJumps = jumpCount
  • 优点:改为 3 段跳、4 段跳只需改一个数字,代码不用动
  • 问自己:remainingJumps 什么时候扣?什么时候重置?

2. 重置时机 —— "跳"这个状态何时结束

核心问题:二段跳的"次数"在什么时候补回来?

方案 行为 手感
落地重置 碰到地面才能再次二段跳 标准平台跳跃,最常用
接触墙壁重置 贴墙也能补跳 适合有爬墙机制的游戏
每 X 秒恢复一次 空中待一会儿又能跳 节奏较怪,很少用

当前项目有 isGrounded,落地重置是最自然的选择。

3. 跳跃力设计 —— 二段跳应该和第一段一样高吗?

方案 效果 代表游戏
相同 jumpForce 两段跳一样高,手感直接 空洞骑士(部分技能)
稍弱(如 jumpForce × 0.8 第二段更低,更真实 蔚蓝 Celeste
固定低值 二段跳只用来"续一下" 大乱斗

可以先设两个独立参数 jumpForcedoubleJumpForce,分别调。

4. 需要考虑的边界问题

问题 说明
走边缘掉落 从平台边缘走下来(没按跳),空中能二段跳吗?通常可以
没用第一段跳 跳过一次后空中还能跳一次?还是说必须先用一次跳?取决于设计
Coyote Time 离开地面后很短时间(如 0.1s)内按跳还算落地跳吗?和剩余次数如何叠加?
动画反馈 二段跳时播放不同的动画(如翻转、翅膀),让玩家感知到"我用了二段跳"
只能一次 二段跳用完没落地之前,不能再获得跳跃次数

5. 建议的切入顺序

  1. 先把计数器机制做出来(jumpCount / remainingJumps
  2. jump() 中把 if(isGrounded) 改为 if(remainingJumps > 0)
  3. 落地时重置 remainingJumps = jumpCount
  4. doubleJumpForce 找手感
  5. 加动画区分一段跳和二段跳

2026-05-25