feat(feedback): 命中/受击反馈支持固定位置与击中位置两种生成模式

DamageInfo 新增运行时字段 HitPoint:HitBox 结算时写入精确接触点
(ClosestPoint),HurtBox.ReceiveDamage 以解析后命中点兜底盖戳,
陷阱/环境等直调路径同样可用。IFeedbackPlayer.PlayHit/PlayTakeHit
增加命中点参数,全链路(武器实例→PlayerCombat→HurtState→
EnemyFeedback)透传。各 Feedback 组件命中/受击槽位新增
FeedbackPositionMode(Fixed=反馈链编排的固定位置 /
HitPoint=传入命中点,启用位置选项的模块在该点生成),由编排
反馈链的开发者在 Inspector 按表现选择;武器命中默认 HitPoint
(火花贴点),角色级默认 Fixed(震屏/振动与位置无关)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 11:48:37 +08:00
parent 5ccab35948
commit 09bdda970a
10 changed files with 93 additions and 29 deletions

View File

@@ -92,7 +92,7 @@ namespace BaseGames.Player
var weight = info.FinalDamage <= 5 ? HitWeight.Light
: info.FinalDamage <= 15 ? HitWeight.Medium
: HitWeight.Heavy;
_feedback.PlayHit(weight);
_feedback.PlayHit(weight, info.HitPoint);
// 攻击命中反嵈:向攻击反方向施加微小后退冲量,增强打击感
if (_movement?.Rb != null && info.KnockbackDirection.x != 0f)

View File

@@ -10,14 +10,16 @@ namespace BaseGames.Player.States
/// </summary>
public class HurtState : PlayerStateBase
{
private float _timer;
private bool _ended;
private float _timer;
private bool _ended;
private Vector3 _hitPoint;
public HurtState(PlayerController owner) : base(owner) { }
public void Initialize(BaseGames.Combat.DamageInfo info)
{
// 由 PlayerController.TakeDamage 传入伤害信息
_hitPoint = info.HitPoint;
if (info.KnockbackForce > 0.01f)
Move?.ApplyKnockback(info.KnockbackDirection, info.KnockbackForce);
}
@@ -28,7 +30,7 @@ namespace BaseGames.Player.States
_timer = Owner.AnimConfig?.HurtDuration ?? 0.4f;
_ended = false;
Stats?.BeginInvincibility();
Feedback.PlayTakeHit();
Feedback.PlayTakeHit(_hitPoint);
if (AnimCfg?.Hurt != null)
{

View File

@@ -53,7 +53,7 @@ namespace BaseGames.Player
var weight = info.FinalDamage <= 5 ? HitWeight.Light
: info.FinalDamage <= 15 ? HitWeight.Medium
: HitWeight.Heavy;
_feedback.PlayHit(weight);
_feedback.PlayHit(weight, info.HitPoint);
OnHitConfirmed?.Invoke(info);
if (_activeDir == AttackDirection.Down)
@@ -66,7 +66,7 @@ namespace BaseGames.Player
/// </summary>
private void OnAnyBreakableHitConfirmed(DamageInfo info)
{
_feedback.PlayHit(HitWeight.Light);
_feedback.PlayHit(HitWeight.Light, info.HitPoint);
if (_activeDir == AttackDirection.Down)
OnDownHitConfirmed?.Invoke(info);
}