Files
zeling_v2/Assets/_Game/Scripts/Enemies/EnemyStatsSO.cs
T
joywayerandClaude Opus 5 0a92d21ce1 fix(enemy): 应用 Task 3 代码审查意见
补上池化路径的防重复记忆重置——ResetRepeatMemory 此前文档承诺了
「对象池复用时清除」却无任何调用点,而它要取代的 BossBase.LastUsedSkillId
恰好在 OnSpawn 里有重置。放 EnemyBase.OnSpawn 以覆盖全部池化敌人。

折扣系数改为每次选招前刷新,与 attackSelectionMode 的读取时机对齐——
此前策划在播放模式下调系数无效、调模式却立即生效,容易误判为功能没生效。
默认值收敛为 EnemyAttackSelector.DefaultAntiRepeatFactor 单一常量。

测试:IneligiblePrevious 用例改用系数 0.5——原先用 0 时,把折扣错写在
eligibility 归零之前也照样通过,是个永远不会失败的测试;统计用例边界由
7σ 收紧到 5σ 使其真正验证该系数;补 ResetRepeatMemory 的确定性用例、
系数 1.0 无惩罚、三候选三条。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 13:00:28 +08:00

67 lines
2.7 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 System;
using UnityEngine;
namespace BaseGames.Enemies
{
/// <summary>
/// 受击分级配置(KnockUp 击飞门槛 & 飞行参数)。
/// 挂载在 EnemyStatsSO.HitTiers 中。
/// </summary>
[Serializable]
public struct HitTierConfig
{
[Tooltip("击飞(KnockUp)触发伤害阈值;需同时设置 DamageFlags.Launch0 = 仅依赖 Launch 标志")]
[Min(0)] public int launchThreshold;
[Tooltip("击飞纵向冲量")]
[Min(0f)] public float launchUpForce;
[Tooltip("击飞横向冲量(沿受击反方向)")]
[Min(0f)] public float launchHorzForce;
[Tooltip("无 KnockUp 动画时的状态持续时长(s")]
[Min(0f)] public float knockUpDuration;
}
/// <summary>
/// 敌人属性配置 SO(架构 07_EnemyModule §2)。
/// </summary>
[CreateAssetMenu(menuName = "BaseGames/Enemies/EnemyStats")]
public class EnemyStatsSO : ScriptableObject
{
[Header("生命")]
[Min(1)] public int MaxHP = 50;
[Header("防御")]
[Min(0)] public int Defense = 0;
[Header("移动")]
[Min(0f)] public float WalkSpeed = 2f;
[Min(0f)] public float RunSpeed = 4f;
[Header("战斗")]
[Min(0f)] public float AttackCooldown = 1f;
[Header("攻击选招策略")]
[Tooltip("到攻击范围内如何从多个候选招里选一个")]
public BaseGames.Enemies.Abilities.AttackSelectionMode attackSelectionMode
= BaseGames.Enemies.Abilities.AttackSelectionMode.WeightedRandom;
[Tooltip("WeightedRandomAntiRepeat 模式下,上一次选中的招的权重折扣系数。" +
"0 = 有替代招时绝不连续重复;1 = 不惩罚。仅该模式生效")]
[Range(0f, 1f)] public float attackAntiRepeatFactor
= BaseGames.Enemies.Abilities.EnemyAttackSelector.DefaultAntiRepeatFactor;
[Header("追击 & AI 阶段")]
[Tooltip("是否有警觉状态:勾选=未发现态进入视野先进警觉(朝向+警觉动画)再追击;不勾选=进入追逐感知直接追击")]
public bool HasAlertState = true;
[Tooltip("最大追击距离(m);超出后放弃追击切换搜查阶段")]
[Min(0f)] public float MaxChaseDistance = 15f;
[Tooltip("视线丢失判定超时(s);超过此时长无视线则切换搜查")]
[Min(0f)] public float LoseLinkTimeout = 2f;
[Tooltip("归位到达判定半径(m")]
[Min(0.01f)] public float HomeRadius = 0.5f;
[Header("受击分级")]
[Tooltip("Stagger / KnockUp 伤害阈值及击飞参数")]
public HitTierConfig HitTiers;
}
}