摄像机区域的优化

This commit is contained in:
2026-05-17 07:56:12 +08:00
parent f264329751
commit d25f237e76
62 changed files with 25774 additions and 5450 deletions

View File

@@ -5,7 +5,7 @@ namespace BaseGames.Player.States
/// <summary>
/// 空中冲刺状态(架构 05_PlayerModule §12
/// 与地面 DashState 独立,消耗 MaxAerialDashes 次数;
/// 空中冲刺可向任意方向(使用移动输入方向,无输入则使用朝向)。
/// 冲刺方向在进入时锁定为当前朝向(进入时锁定朝向,冲刺期间不可通过输入改变方向)。
/// </summary>
public class AerialDashState : PlayerStateBase
{
@@ -41,10 +41,9 @@ namespace BaseGames.Player.States
dashState.ResetInvincibilityCooldown(Cfg.DashInvincibilityCooldown);
}
// 关闭重力,施加冲刺速度(空中冲刺不改变垂直速度
// 关闭重力,施加冲刺速度(方向锁定为进入时朝向,不受输入影响
Move?.SetGravityScale(0f);
float dir = Input.MoveInput.x != 0 ? Mathf.Sign(Input.MoveInput.x) : _facingDir;
Move?.Dash(new Vector2(dir, 0f), Cfg.DashSpeed);
Move?.Dash(new Vector2(_facingDir, 0f), Cfg.DashSpeed);
// 播放冲刺动画(复用地面冲刺动画)
if (AnimCfg?.Dash != null) Anim?.Play(AnimCfg.Dash);
@@ -54,6 +53,15 @@ namespace BaseGames.Player.States
{
_timer -= Time.deltaTime;
if (_timer <= 0f)
{
Move?.SetGravityScale(Cfg.DefaultGravityScale);
Owner.TransitionTo(Owner.GetState<FallState>());
return;
}
// 撞墙立即终止冲刺(碰到实体墙立即中止,避免压墙卡住)
var wd = Owner.WallDetector;
if (wd != null && wd.IsTouchingWall && wd.WallDirection == _facingDir)
{
Move?.SetGravityScale(Cfg.DefaultGravityScale);
Owner.TransitionTo(Owner.GetState<FallState>());
@@ -67,12 +75,9 @@ namespace BaseGames.Player.States
public override void OnStateFixedUpdate()
{
// 冲刺期间锁定速度
// 冲刺期间保持锁定方向速度(与 DashState 一致,使用 _facingDir
if (_timer > 0f)
{
float dir = Input.MoveInput.x != 0 ? Mathf.Sign(Input.MoveInput.x) : _facingDir;
Move?.Dash(new Vector2(dir, 0f), Cfg.DashSpeed);
}
Move?.Dash(new Vector2(_facingDir, 0f), Cfg.DashSpeed);
}
/// <summary>着地时重置空中冲刺次数(由 PlayerController 在着地时调用)。</summary>

View File

@@ -47,7 +47,7 @@ namespace BaseGames.Player.States
// 无敌帧:
// 条件 1已解锁 InvincibleDash
// 条件 2无敌冷却已就绪防止 spam 冲刺连序无敌)
// 窗口时长 = DashInvincibilityDuration < DashDuration冲刺后段无保护(对齐 HK
// 窗口时长 = DashInvincibilityDuration < DashDuration冲刺后段无保护
if (Stats != null && Stats.HasAbility(AbilityType.InvincibleDash) && CanGrantInvincibility)
{
Stats.BeginInvincibility(Cfg.DashInvincibilityDuration);
@@ -66,6 +66,14 @@ namespace BaseGames.Player.States
{
_timer -= Time.deltaTime;
if (_timer <= 0f)
{
EndDash();
return;
}
// 撞墙立即终止冲刺(碰到实体墙立即中止,避免压墙卡住)
var wd = Owner.WallDetector;
if (wd != null && wd.IsTouchingWall && wd.WallDirection == _facingDir)
EndDash();
}

View File

@@ -3,7 +3,7 @@ using UnityEngine;
namespace BaseGames.Player.States
{
/// <summary>
/// 下落状态(对齐空洞骑士手感)
/// 下落状态。
/// - 郊狼跳CoyoteTimer > 0 时按跳跃 → 一段跳JumpState使用 JumpForce
/// - 二段跳CoyoteTimer 耗尽后按跳跃且 AirJumpsLeft > 0 → JumpState使用 DoubleJumpForce
/// - 空中冲刺HasAbility(AirDash) && HasAerialDash → AerialDashState。
@@ -38,7 +38,7 @@ namespace BaseGames.Player.States
_owner.TransitionTo(_owner.GetState<JumpState>());
return;
}
// 无跳跃机会:输入已消耗,静默忽略(HK 相同行为
// 无跳跃机会:输入已消耗,静默忽略(无可用跳跃机会时静默消耗输入缓冲
}
// ── 空中冲刺────────────────────────────────────────────────────────
@@ -64,14 +64,17 @@ namespace BaseGames.Player.States
return;
}
// 空中水平移动
if (Mathf.Abs(Input.MoveInput.x) > 0.01f)
Move.Move(Input.MoveInput.x * Cfg.RunSpeed);
}
public override void OnStateFixedUpdate()
{
// 增强下落重力FallGravityMult 对齐 HK下落比上升更快
// 空中水平移动:有输入时立即覆盖至目标速度;无输入时施加空气阻力保留动量
if (Mathf.Abs(Input.MoveInput.x) > 0.01f)
Move.Move(Input.MoveInput.x * Cfg.RunSpeed);
else
Move.ApplyAirDrag(Cfg.AirDragFactor);
// 增强下落重力FallGravityMult下落比上升更快手感更紧实
if (Move.Rb.velocity.y < 0f)
{
float extraGrav = Physics2D.gravity.y * (Cfg.FallGravityMult - 1f) * Time.fixedDeltaTime;

View File

@@ -3,9 +3,9 @@ using UnityEngine;
namespace BaseGames.Player.States
{
/// <summary>
/// 跳跃状态(对齐空洞骑士手感)
/// 跳跃状态。
/// - 一段跳 / 郊狼跳OnStateEnter 时调用 Move.Jump()。
/// - 二段跳(Monarch Wings 等效):上升或下落途中再按跳跃且 AirJumpsLeft > 0
/// - 二段跳(二段跳能力解锁后可用):上升或下落途中再按跳跃且 AirJumpsLeft > 0
/// 调用 Move.DoubleJump(),重播跳跃动画,不离开本状态(保持速度截断逻辑)。
/// - 空中冲刺:上升途中按冲刺且 HasAbility(AirDash) → AerialDashState。
/// - 变高跳:松开跳跃键触发 JumpCancelledEvent → CutJump()(系数 = JumpCutMultiplier
@@ -59,7 +59,7 @@ namespace BaseGames.Player.States
}
}
// 二段跳:上升阶段即可触发(类比 HK Monarch Wings随时可二段跳)
// 二段跳:上升阶段即可触发(上升途中任意时刻可二段跳)
if (Buffer.ConsumeJump() && Owner.AirJumpsLeft > 0)
{
Owner.UseAirJump();
@@ -68,10 +68,15 @@ namespace BaseGames.Player.States
if (AnimCfg?.Jump != null) Anim?.Play(AnimCfg.Jump);
return;
}
}
// 水平移动HK 空中控制:与跑步同速)
public override void OnStateFixedUpdate()
{
// 空中水平移动:有输入时立即覆盖至目标速度;无输入时施加空气阻力保留动量
if (Mathf.Abs(Input.MoveInput.x) > 0.01f)
Move.Move(Input.MoveInput.x * Cfg.RunSpeed);
else
Move.ApplyAirDrag(Cfg.AirDragFactor);
}
public override void OnStateExit()

View File

@@ -105,7 +105,8 @@ namespace BaseGames.Player.States
// ── IPoiseSource 实现(架构 06_CombatModule §13─────────────────────
/// <summary>
/// 玩家不拥有霸体,始终返回 <see cref="PoiseLevel.None"/>。
/// 设计决策:类似 Hollow Knight玩家依靠走位和弹反规避伤害而非硬吃
/// 设计决策:玩家不拥有霸体,始终返回 <see cref="PoiseLevel.None"/>
/// 玩家依靠走位和弹反规避伤害而非硬吃,以保持战斗的负担感和张力。
/// 若未来需要临时霸体(如特定技能动作),请通过独立的覆盖标记实现,
/// 而非在此处引入状态,以保持接口语义清晰。
/// </summary>

View File

@@ -38,6 +38,7 @@ namespace BaseGames.Player.States
}
if (Mathf.Abs(Input.MoveInput.x) < 0.1f)
{
Move.ZeroHorizontalVelocity();
_owner.TransitionTo(_owner.GetState<IdleState>());
return;
}
@@ -45,7 +46,11 @@ namespace BaseGames.Player.States
public override void OnStateFixedUpdate()
{
Move.Move(Input.MoveInput.x * Cfg.RunSpeed);
float inputX = Input.MoveInput.x;
if (Mathf.Abs(inputX) > 0.1f)
Move.Move(inputX * Cfg.RunSpeed);
else
Move.ZeroHorizontalVelocity();
}
}
}

View File

@@ -39,14 +39,17 @@ namespace BaseGames.Player.States
public override void OnStateUpdate()
{
_inputLockTimer -= Time.deltaTime;
// 上升结束 → 下落
if (!Move.IsRising)
{
Owner.TransitionTo(Owner.GetState<FallState>());
return;
}
}
public override void OnStateFixedUpdate()
{
_inputLockTimer -= Time.fixedDeltaTime;
// 输入锁结束后允许水平控制
if (_inputLockTimer <= 0f && Mathf.Abs(Input.MoveInput.x) > 0.01f)