左右翻转的本质
2D Sprite 默认位于 XY 平面并面向相机。左右翻转的目标是让画面的 X 方向反转,而不是让角色在 XY 平面中旋转。
facingDir 与 facingRight:逻辑朝向
当前代码把两个朝向成员写成:
facingDir 在 1 和 -1 之间切换,表达可参与计算的方向符号。当前 PlayerDashState 使用 player.dashSpeed * player.facingDir 决定向右或向左冲刺。facingRight 在 true 和 false 之间切换,表达 Player 内部判断用的“当前是否朝右”。这两个成员保存逻辑朝向;真正改变画面的是后面的翻转操作。逻辑状态、速度方向和视觉状态必须保持一致。
facingDir 为什么使用只读属性
facingDir 是自动属性,不是普通 public 字段:public get 允许 PlayerDashState 等外部状态读取 player.facingDir;private set 禁止外部状态直接赋值,只有 Player 内部的 Flip 可以修改它。这样可以防止其他状态只改 facingDir,却没有同步 facingRight 和 Transform。Transform.Rotate:绕 Y 轴实现镜像
transform.Rotate(0f, 180f, 0f) 在当前旋转基础上绕 Y 轴旋转 180°。对于正面朝向相机的 Sprite,Y 轴旋转会让局部 X 轴反向,所以从相机看来是左右镜像。
Rotate 是相对旋转方法,每次调用都会在现有角度上继续增加 180°。transform.rotation 则是保存完整旋转结果的 Quaternion 属性。Transform.rotation 与 Rigidbody2D.rotation
transform.rotation:- 类型是 Quaternion。
- 能表达 X、Y、Z 三个轴的完整旋转。
- 绕 Y 轴 180°可以造成 Sprite 左右镜像。
Rigidbody2D.rotation:- 类型是 float,单位为度。
- 只表示绕 Z 轴的 2D 物理旋转。
- Z 轴旋转发生在屏幕平面内,180°会把角色倒转。
因此 Rigidbody2D.rotation 不是左右镜像接口。只有角色的 Collider 和物理身体确实需要在 XY 平面中转动时,才使用它或
MoveRotation。SpriteRenderer.flipX:只翻转图片
flipX 在 SpriteRenderer 内部反转 Sprite 的 X 方向,只改变渲染结果,不旋转 Rigidbody2D、Collider2D 和 Transform 坐标系。只有角色图片需要左右翻转时,flipX 的职责最明确。
Visual 子节点翻转:翻转一组视觉对象
把 SpriteRenderer 和需要一起镜像的视觉挂点放在 Visual 下,只旋转 Visual,可以让整组画面一起翻转,同时保持 PlayerRoot 的 Rigidbody2D 和 Collider2D 不变。
直接指定朝右为 0°、朝左为 180°,表达的是目标状态;连续调用 Rotate 表达的是在当前状态上继续旋转。
三种接口的职责
- SpriteRenderer.flipX:镜像一张 Sprite 的渲染结果。
- Visual.localRotation:镜像整个视觉子层级。
- Rigidbody2D.rotation / MoveRotation:真实旋转 2D 物理身体和 Collider。
左右朝向首先是视觉问题。只有物理形状也需要跟着转动时,它才是 Rigidbody2D 的旋转问题。