From 5922ef373d3d781ab1e30bd571c1f1a03f75be6d Mon Sep 17 00:00:00 2001 From: Joywayer Date: Fri, 12 Jun 2026 10:43:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(combat):=20=E5=BC=B9=E5=8F=8D=E6=8A=95?= =?UTF-8?q?=E5=B0=84=E7=89=A9=E4=BC=A4=E5=AE=B3=E7=9B=AE=E6=A0=87=E5=B1=82?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=98=BE=E5=BC=8F=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ProjectileConfigSO 新增 ReflectedTargetLayers:弹反后写入 HitBox.TargetLayers 的目标层显式配置;留空(Nothing)有明确缺省语义=自动翻转(PlayerHurtBox 位换 EnemyHurtBox 位、其余位保留)。Projectile/ParryableProjectile 两条弹反路径统一走 ApplyReflectedTargetLayers。现有 6 个投射物配置资产已显式配为 EnemyHurtBox。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../Projectiles/PROJ_Boomerang_Config.asset | 4 ++++ .../Projectiles/PROJ_FeiZhi_Acid_Config.asset | 4 ++++ .../Projectiles/PROJ_TornadoLarge_Config.asset | 4 ++++ .../Projectiles/PROJ_TornadoSmall_Config.asset | 4 ++++ .../Projectiles/PROJ_WindStone_Config.asset | 4 ++++ .../Projectiles/PROJ_ZhiMu_Acid_Config.asset | 4 ++++ .../_Game/Scripts/Combat/ParryableProjectile.cs | 4 ++-- Assets/_Game/Scripts/Combat/Projectile.cs | 17 ++++++++++++----- .../_Game/Scripts/Combat/ProjectileConfigSO.cs | 3 +++ 9 files changed, 41 insertions(+), 7 deletions(-) diff --git a/Assets/_Game/Data/Combat/Projectiles/PROJ_Boomerang_Config.asset b/Assets/_Game/Data/Combat/Projectiles/PROJ_Boomerang_Config.asset index 7c0c402..17b1d4b 100644 --- a/Assets/_Game/Data/Combat/Projectiles/PROJ_Boomerang_Config.asset +++ b/Assets/_Game/Data/Combat/Projectiles/PROJ_Boomerang_Config.asset @@ -13,6 +13,7 @@ MonoBehaviour: m_Name: PROJ_Boomerang_Config m_EditorClassIdentifier: DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2} + MaxHits: 1 Speed: 10 Lifetime: 6 LaunchAngleDeg: 0 @@ -21,3 +22,6 @@ MonoBehaviour: PoolKey: PROJ_Boomerang ParrySpeedMultiplier: 1.2 ParryDamageMultiplier: 2 + ReflectedTargetLayers: + serializedVersion: 2 + m_Bits: 134217728 diff --git a/Assets/_Game/Data/Combat/Projectiles/PROJ_FeiZhi_Acid_Config.asset b/Assets/_Game/Data/Combat/Projectiles/PROJ_FeiZhi_Acid_Config.asset index 1fdc527..d19a6ca 100644 --- a/Assets/_Game/Data/Combat/Projectiles/PROJ_FeiZhi_Acid_Config.asset +++ b/Assets/_Game/Data/Combat/Projectiles/PROJ_FeiZhi_Acid_Config.asset @@ -13,6 +13,7 @@ MonoBehaviour: m_Name: PROJ_FeiZhi_Acid_Config m_EditorClassIdentifier: DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2} + MaxHits: 1 Speed: 9 Lifetime: 4 LaunchAngleDeg: 45 @@ -21,3 +22,6 @@ MonoBehaviour: PoolKey: PROJ_FeiZhi_Acid ParrySpeedMultiplier: 1.2 ParryDamageMultiplier: 2 + ReflectedTargetLayers: + serializedVersion: 2 + m_Bits: 134217728 diff --git a/Assets/_Game/Data/Combat/Projectiles/PROJ_TornadoLarge_Config.asset b/Assets/_Game/Data/Combat/Projectiles/PROJ_TornadoLarge_Config.asset index ab7074f..237ad57 100644 --- a/Assets/_Game/Data/Combat/Projectiles/PROJ_TornadoLarge_Config.asset +++ b/Assets/_Game/Data/Combat/Projectiles/PROJ_TornadoLarge_Config.asset @@ -13,6 +13,7 @@ MonoBehaviour: m_Name: PROJ_TornadoLarge_Config m_EditorClassIdentifier: DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2} + MaxHits: 1 Speed: 0 Lifetime: 5 LaunchAngleDeg: 0 @@ -21,3 +22,6 @@ MonoBehaviour: PoolKey: PROJ_TornadoLarge ParrySpeedMultiplier: 1.2 ParryDamageMultiplier: 2 + ReflectedTargetLayers: + serializedVersion: 2 + m_Bits: 134217728 diff --git a/Assets/_Game/Data/Combat/Projectiles/PROJ_TornadoSmall_Config.asset b/Assets/_Game/Data/Combat/Projectiles/PROJ_TornadoSmall_Config.asset index a917ad6..65c6054 100644 --- a/Assets/_Game/Data/Combat/Projectiles/PROJ_TornadoSmall_Config.asset +++ b/Assets/_Game/Data/Combat/Projectiles/PROJ_TornadoSmall_Config.asset @@ -13,6 +13,7 @@ MonoBehaviour: m_Name: PROJ_TornadoSmall_Config m_EditorClassIdentifier: DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2} + MaxHits: 1 Speed: 7 Lifetime: 4 LaunchAngleDeg: 0 @@ -21,3 +22,6 @@ MonoBehaviour: PoolKey: PROJ_TornadoSmall ParrySpeedMultiplier: 1.2 ParryDamageMultiplier: 2 + ReflectedTargetLayers: + serializedVersion: 2 + m_Bits: 134217728 diff --git a/Assets/_Game/Data/Combat/Projectiles/PROJ_WindStone_Config.asset b/Assets/_Game/Data/Combat/Projectiles/PROJ_WindStone_Config.asset index e499d07..8b15c24 100644 --- a/Assets/_Game/Data/Combat/Projectiles/PROJ_WindStone_Config.asset +++ b/Assets/_Game/Data/Combat/Projectiles/PROJ_WindStone_Config.asset @@ -13,6 +13,7 @@ MonoBehaviour: m_Name: PROJ_WindStone_Config m_EditorClassIdentifier: DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2} + MaxHits: 1 Speed: 6 Lifetime: 4 LaunchAngleDeg: -90 @@ -21,3 +22,6 @@ MonoBehaviour: PoolKey: PROJ_WindStone ParrySpeedMultiplier: 1.2 ParryDamageMultiplier: 2 + ReflectedTargetLayers: + serializedVersion: 2 + m_Bits: 134217728 diff --git a/Assets/_Game/Data/Combat/Projectiles/PROJ_ZhiMu_Acid_Config.asset b/Assets/_Game/Data/Combat/Projectiles/PROJ_ZhiMu_Acid_Config.asset index bcfe846..201e254 100644 --- a/Assets/_Game/Data/Combat/Projectiles/PROJ_ZhiMu_Acid_Config.asset +++ b/Assets/_Game/Data/Combat/Projectiles/PROJ_ZhiMu_Acid_Config.asset @@ -13,6 +13,7 @@ MonoBehaviour: m_Name: PROJ_ZhiMu_Acid_Config m_EditorClassIdentifier: DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2} + MaxHits: 1 Speed: 9 Lifetime: 4 LaunchAngleDeg: 45 @@ -21,3 +22,6 @@ MonoBehaviour: PoolKey: PROJ_ZhiMu_Acid ParrySpeedMultiplier: 1.2 ParryDamageMultiplier: 2 + ReflectedTargetLayers: + serializedVersion: 2 + m_Bits: 134217728 diff --git a/Assets/_Game/Scripts/Combat/ParryableProjectile.cs b/Assets/_Game/Scripts/Combat/ParryableProjectile.cs index 5541db2..bfc0a3c 100644 --- a/Assets/_Game/Scripts/Combat/ParryableProjectile.cs +++ b/Assets/_Game/Scripts/Combat/ParryableProjectile.cs @@ -36,10 +36,10 @@ namespace BaseGames.Combat // 阵营随弹反翻转:切到 PlayerProjectile 层(否则碰撞矩阵 // EnemyProjectile↔EnemyHurtBox 不碰撞,反射后永远打不中敌人), - // 伤害目标层同步从玩家侧切到敌人侧。 + // 伤害目标层同步切换(优先取配置的 ReflectedTargetLayers)。 int playerProjLayer = LayerMask.NameToLayer("PlayerProjectile"); if (playerProjLayer >= 0) gameObject.layer = playerProjLayer; - RetargetToEnemyFaction(); + ApplyReflectedTargetLayers(); if (_reflectSource != null) DamageInfo = DamageInfo.From(_reflectSource); diff --git a/Assets/_Game/Scripts/Combat/Projectile.cs b/Assets/_Game/Scripts/Combat/Projectile.cs index a08fc0a..e6f1acb 100644 --- a/Assets/_Game/Scripts/Combat/Projectile.cs +++ b/Assets/_Game/Scripts/Combat/Projectile.cs @@ -87,8 +87,8 @@ namespace BaseGames.Combat // 重置 HitBox 命中记录,确保反射后可命中新目标 _hitBox.Deactivate(); _hitBox.Activate(_config?.DamageSource); - // 伤害目标随阵营翻转:玩家侧 → 敌人侧 - RetargetToEnemyFaction(); + // 伤害目标随阵营切换(优先取配置的显式目标层) + ApplyReflectedTargetLayers(); // 反射后重置命中预算,并跳过本次(弹反)命中的扣减,避免反射后立即被回收 _hitsRemaining = _maxHits; @@ -96,11 +96,18 @@ namespace BaseGames.Combat } /// - /// 弹反换阵营后,把伤害目标从玩家侧切到敌人侧 - /// (仅交换 PlayerHurtBox→EnemyHurtBox 位,保留可破坏物等其他目标层)。 + /// 弹反换阵营后应用伤害目标层: + /// 优先使用 的显式配置; + /// 未配置(Nothing)时自动翻转——仅交换 PlayerHurtBox→EnemyHurtBox 位, + /// 保留可破坏物等其他目标层。 /// - protected void RetargetToEnemyFaction() + protected void ApplyReflectedTargetLayers() { + if (_config != null && _config.ReflectedTargetLayers.value != 0) + { + _hitBox.TargetLayers = _config.ReflectedTargetLayers; + return; + } int playerHurt = LayerMask.NameToLayer("PlayerHurtBox"); int enemyHurt = LayerMask.NameToLayer("EnemyHurtBox"); if (playerHurt < 0 || enemyHurt < 0) return; // Layer 尚未创建,保留现有掩码 diff --git a/Assets/_Game/Scripts/Combat/ProjectileConfigSO.cs b/Assets/_Game/Scripts/Combat/ProjectileConfigSO.cs index 0aeb14f..908f4c0 100644 --- a/Assets/_Game/Scripts/Combat/ProjectileConfigSO.cs +++ b/Assets/_Game/Scripts/Combat/ProjectileConfigSO.cs @@ -26,5 +26,8 @@ namespace BaseGames.Combat [Header("弹反")] public float ParrySpeedMultiplier = 1.2f; public float ParryDamageMultiplier = 2.0f; + [Tooltip("弹反后本投射物可造成伤害判定的 Layer(显式配置,写入 HitBox.TargetLayers)。" + + "留空(Nothing) = 自动翻转:在原目标层基础上 PlayerHurtBox 位换为 EnemyHurtBox 位、其余位保留。")] + public LayerMask ReflectedTargetLayers; } }