using UnityEngine; using BaseGames.Parry; namespace BaseGames.Combat { /// /// 可被玩家弹反的抛射物。 /// 触发时优先检测弹反窗口;若成功弹反则反向飞行并可切换伤害源; /// 否则走正常伤害流水线。 /// 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(); if (parrySystem != null && parrySystem.IsParrying && parrySystem.ConsumeParry()) { _reflected = true; Direction = -Direction; _rb.velocity = Direction * _config.Speed * _config.ParrySpeedMultiplier; // 阵营随弹反翻转:切到 PlayerProjectile 层(否则碰撞矩阵 // EnemyProjectile↔EnemyHurtBox 不碰撞,反射后永远打不中敌人), // 伤害目标层同步从玩家侧切到敌人侧。 int playerProjLayer = LayerMask.NameToLayer("PlayerProjectile"); if (playerProjLayer >= 0) gameObject.layer = playerProjLayer; RetargetToEnemyFaction(); if (_reflectSource != null) DamageInfo = DamageInfo.From(_reflectSource); return; } } // ── 正常命中 ───────────────────────────────────────────────── // 本类绕过 HitBox 自行判定,需自行套用其伤害目标层过滤 if ((_hitBox.TargetLayers.value & (1 << other.gameObject.layer)) == 0) return; var hurtBox = other.GetComponent(); if (hurtBox != null) { hurtBox.ReceiveDamage(DamageInfo); ReturnToPool(); } } protected override void OnDisable() { base.OnDisable(); _reflected = false; } } }