Files
zeling_v2/Assets/_Game/Scripts/Player/States/DownAttackState.cs
Joywayer 8515dfa7ab feat(combat): 下劈弹跳完善——可破坏物可弹跳+独立弹跳力+下劈保留空中操控
- HitBox 新增 OnBreakableHitConfirmed:命中 IBreakable 也发命中确认,
  下劈打可破坏物同样弹跳;不走 OnHitConfirmed,灵力仍只来自敌人
- 新增 PogoBounceForce 配置(默认 15,略低于 JumpForce=18)+
  PlayerMovement.PogoBounce(),弹跳高度独立可调、固定不可截断
- DownAttackState 增加 OnStateFixedUpdate:下劈期间保留完整空中
  水平操控(含与 FallState 同款贴墙保护)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 09:51:17 +08:00

105 lines
3.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
using BaseGames.Combat;
namespace BaseGames.Player.States
{
/// <summary>
/// 下劈(踩踏 Pogo状态架构 05_PlayerModule §2
/// 需解锁 AbilityType.DownSlash 才能进入;
/// 激活 HitBoxDown着地或命中后弹跳。
/// </summary>
public class DownAttackState : PlayerStateBase
{
private bool _hasHitEnemy;
private bool _exited;
public DownAttackState(PlayerController owner) : base(owner) { }
public override void OnStateEnter()
{
_hasHitEnemy = false;
_exited = false;
if (Owner.Combat != null)
Owner.Combat.OnDownHitConfirmed += OnDownHitConfirmed;
var step = Owner.Weapon?.ActiveWeapon?.GetDirStep(AttackDirection.Down);
float spd = Stats?.AnimatorSpeedMultiplier ?? 1f;
if (step?.clip?.Clip != null)
{
var animState = Anim.Play(step.Value.clip);
animState.Speed *= spd;
var events = animState.Events(this);
events.OnEnd = OnClipEnd;
var s = step.Value;
events.Add(s.hitBoxEnter, () => Owner.Combat?.EnableWeaponHitBox(AttackDirection.Down, s.hitBoxId));
events.Add(step.Value.hitBoxExit, () => Owner.Combat?.DisableAllWeaponHitBoxes());
}
else
{
Owner.Combat?.EnableWeaponHitBox(AttackDirection.Down);
OnClipEnd();
}
// 下劈为纯向下攻击:保持角色原有的自然下落,不额外施加向下俯冲位移
// (俯冲位移会让下劈手感变成下冲,命中弹跳逻辑见 OnDownHitConfirmed
}
public override void OnStateExit()
{
_exited = true;
if (Owner.Combat != null)
Owner.Combat.OnDownHitConfirmed -= OnDownHitConfirmed;
Owner.Combat?.DisableAllWeaponHitBoxes();
}
private void OnDownHitConfirmed(BaseGames.Combat.DamageInfo _)
{
if (_hasHitEnemy) return;
_hasHitEnemy = true;
// Pogo 弹跳:命中后向上弹起(独立弹跳力,略矮于满跳),同时重置空中能力(等同落地效果)
Owner.ResetAirJumps();
Owner.GetState<DashState>()?.ResetDashCharge();
Move.PogoBounce();
}
public override void OnStateUpdate()
{
// 着地时回到 Idle / Run
if (Move.IsGrounded)
{
Owner.TransitionTo(Owner.GetState<IdleState>());
}
}
public override void OnStateFixedUpdate()
{
// 下劈期间保留完整空中水平操控(与 FallState 同款贴墙保护,防止压墙摩擦/卡角)
if (Mathf.Abs(Input.MoveInput.x) > 0.01f)
{
int inputDir = Input.MoveInput.x > 0 ? 1 : -1;
var wd = Owner.WallDetector;
bool currentFrameWall = inputDir > 0 ? Move.IsWallRight : Move.IsWallLeft;
if (currentFrameWall
|| (wd != null && (wd.IsTouchingWall && wd.WallDirection == inputDir
|| wd.HasPartialContact(inputDir))))
Move.ZeroHorizontalVelocity();
else
Move.Move(Input.MoveInput.x * Cfg.RunSpeed);
}
else
Move.ZeroHorizontalVelocity();
}
private void OnClipEnd()
{
if (_exited) return;
if (!Move.IsGrounded)
Owner.TransitionTo(Owner.GetState<FallState>());
else
Owner.TransitionTo(Owner.GetState<IdleState>());
}
}
}