Files
zeling_v2/Assets/_Game/Scripts/Combat/ParryableProjectile.cs
Joywayer 5922ef373d feat(combat): 弹反投射物伤害目标层改为显式配置
ProjectileConfigSO 新增 ReflectedTargetLayers:弹反后写入 HitBox.TargetLayers 的目标层显式配置;留空(Nothing)有明确缺省语义=自动翻转(PlayerHurtBox 位换 EnemyHurtBox 位、其余位保留)。Projectile/ParryableProjectile 两条弹反路径统一走 ApplyReflectedTargetLayers。现有 6 个投射物配置资产已显式配为 EnemyHurtBox。

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

68 lines
2.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.Parry;
namespace BaseGames.Combat
{
/// <summary>
/// 可被玩家弹反的抛射物。
/// 触发时优先检测弹反窗口;若成功弹反则反向飞行并可切换伤害源;
/// 否则走正常伤害流水线。
/// </summary>
public class ParryableProjectile : LinearProjectile
{
[SerializeField] private DamageSourceSO _reflectSource;
private bool _reflected;
protected override void OnInitialized()
{
// 禁用子 HitBox 的自动检测,改由本组件的 OnTriggerEnter2D 手动处理,
// 以便在命中前插入弹反判断。
_hitBox.Deactivate();
_rb.velocity = Direction * _config.Speed;
}
private void OnTriggerEnter2D(Collider2D other)
{
// ── 弹反判断 ────────────────────────────────────────────────
if (!_reflected)
{
var parrySystem = other.GetComponentInParent<ParrySystem>();
if (parrySystem != null && parrySystem.IsParrying && parrySystem.ConsumeParry())
{
_reflected = true;
Direction = -Direction;
_rb.velocity = Direction * _config.Speed * _config.ParrySpeedMultiplier;
// 阵营随弹反翻转:切到 PlayerProjectile 层(否则碰撞矩阵
// EnemyProjectile↔EnemyHurtBox 不碰撞,反射后永远打不中敌人),
// 伤害目标层同步切换(优先取配置的 ReflectedTargetLayers
int playerProjLayer = LayerMask.NameToLayer("PlayerProjectile");
if (playerProjLayer >= 0) gameObject.layer = playerProjLayer;
ApplyReflectedTargetLayers();
if (_reflectSource != null)
DamageInfo = DamageInfo.From(_reflectSource);
return;
}
}
// ── 正常命中 ─────────────────────────────────────────────────
// 本类绕过 HitBox 自行判定,需自行套用其伤害目标层过滤
if ((_hitBox.TargetLayers.value & (1 << other.gameObject.layer)) == 0) return;
var hurtBox = other.GetComponent<HurtBox>();
if (hurtBox != null)
{
hurtBox.ReceiveDamage(DamageInfo);
ReturnToPool();
}
}
protected override void OnDisable()
{
base.OnDisable();
_reflected = false;
}
}
}