Files
zeling_v2/Assets/_Game/Scripts/Enemies/EnemyStatsSO.cs
T
joywayerandClaude Opus 4.8 6c27993e09 feat(ai): 敌人感知↔状态模型——待机/警觉/追击/巡逻 + 可复用感知状态机
感知门面 EnemyBase.InChaseZone(追逐/aggro)/InVisionZone(视野/los,缺省回退aggro),纯查询;
转换逻辑归 AI 层: 新增可复用 PerceptionStateMachine(统一规则,HasAlert/视野缺省自动降级);
规则: 未发现进视野→警觉, 进追逐→追击(委托能力), 追击脱离视野→巡逻(永不回警觉,再进视野再警觉).
EnemyStatsSO.HasAlertState 勾选项; ContactChaseAbility 改纯执行器(退出由AI中断); E001 用可复用件.
PlayMode 验证四态转换全通过.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 15:10:39 +08:00

86 lines
3.6 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("重击(Stagger)触发伤害阈值;伤害 &gt;= 此值进入 Stagger")]
[Min(0)] public int heavyHitThreshold;
[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(0)] public int AttackDamage = 10;
[Min(0f)] public float AttackRange = 1.5f;
[Min(0f)] public float AttackCooldown = 1f;
[Min(0f)] public float DetectRange = 6f;
[Header("追击 & AI 阶段")]
[Tooltip("是否有警觉状态:勾选=未发现态进入视野先进警觉(朝向+警觉动画)再追击;不勾选=进入追逐感知直接追击")]
public bool HasAlertState = true;
[Tooltip("最大追击距离(m);超出后放弃追击切换搜查阶段")]
[Min(0f)] public float MaxChaseDistance = 15f;
[Tooltip("视线丢失判定超时(s);超过此时长无视线则切换搜查")]
[Min(0f)] public float LoseLinkTimeout = 2f;
[Tooltip("Alert 阶段持续时长(s);短暂警觉动作后进入追击")]
[Min(0f)] public float AlertDuration = 0.6f;
[Tooltip("搜查最后可见位置后的等待时长(s)")]
[Min(0f)] public float InvestigateDuration = 3f;
[Tooltip("归位到达判定半径(m")]
[Min(0.01f)] public float HomeRadius = 0.5f;
[Header("击退(作为来源时)")]
[Min(0f)] public float KnockbackForce = 5f;
[Min(0f)] public float HitStunDuration = 0.3f;
[Header("受击分级")]
[Tooltip("Stagger / KnockUp 伤害阈值及击飞参数")]
public HitTierConfig HitTiers;
[Header("视线检测(遗留配置,已迁移到 PhysicsPerceptionSystem 各 Slot 的 losBlockMask")]
[Tooltip("相对 transform.position 的眼睛偏移量")]
public Vector2 EyeOffset = new Vector2(0f, 0.8f);
[Tooltip("遮挡 LOS 的物理图层")]
public LayerMask LOSBlockingMask = 1; // Default layer
[Header("感知角度")]
[Tooltip("前向感知扇形半角(度)。0 = 关闭方向检查,按完整圆形感知")]
[Range(0f, 180f)]
public float DetectAngleDeg = 0f;
[Header("警戒传播(Group Alert")]
[Tooltip("发现玩家时通知周围同伴进入 Alert 的半径(m);0 = 关闭")]
[Min(0f)]
public float AlertBroadcastRadius = 0f;
}
}