feat(enemy): 未发现层三模块(单一态/单向降级/定时交替)

This commit is contained in:
2026-07-29 12:19:26 +08:00
parent 894ae99984
commit acfba66c5d
9 changed files with 231 additions and 0 deletions
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using BaseGames.AI;
namespace BaseGames.Enemies
{
/// <summary>站立 ⇄ 巡逻定时交替,脱战回站立。内部计时边经 Link 挂载,优先级低于骨架升级边。</summary>
[Serializable]
public sealed class AlternatingIdlePatrol : IUnawareModule
{
public const string Idle = "Idle";
public const string Patrol = "Patrol";
static readonly string[] StatesArray = { Idle, Patrol };
[Tooltip("站立停留时长(秒),到点转巡逻")]
[SerializeField, Min(0.1f)] float _idleDwell = 2f;
[Tooltip("巡逻持续时长(秒),到点转站立")]
[SerializeField, Min(0.1f)] float _patrolDwell = 4f;
public AlternatingIdlePatrol() { }
public AlternatingIdlePatrol(float idleDwell, float patrolDwell)
{ _idleDwell = idleDwell; _patrolDwell = patrolDwell; }
public string Entry => Idle;
public string Rest => Idle;
public IReadOnlyList<string> States => StatesArray;
public void Declare(BrainBuilder b)
{
AiStateFragments.Locomotion(b, Idle, LocomotionMode.Idle);
AiStateFragments.Locomotion(b, Patrol, LocomotionMode.Patrol);
}
public void Link(BrainBuilder b)
{
b.State(Idle) .To(Patrol).After(_idleDwell);
b.State(Patrol).To(Idle) .After(_patrolDwell);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e6e5fc2afebbf144b95b40b1f01a038c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using BaseGames.AI;
namespace BaseGames.Enemies
{
/// <summary>
/// 单向降级:出生时伪装静止,一旦交战过就只回巡逻,伪装态不可逆。
/// 刻意不声明两态之间的内部边——伪装只在出生那一次可达。
/// </summary>
[Serializable]
public sealed class DisguiseThenPatrol : IUnawareModule
{
public const string Disguise = "Disguise";
public const string Patrol = "Patrol";
static readonly string[] StatesArray = { Disguise, Patrol };
[Tooltip("出生伪装态的移动模式(通常 Idle)")]
[SerializeField] LocomotionMode _disguiseMode = LocomotionMode.Idle;
[Tooltip("脱战后常态的移动模式(通常 Patrol)")]
[SerializeField] LocomotionMode _patrolMode = LocomotionMode.Patrol;
public DisguiseThenPatrol() { }
public DisguiseThenPatrol(LocomotionMode disguiseMode, LocomotionMode patrolMode)
{ _disguiseMode = disguiseMode; _patrolMode = patrolMode; }
public string Entry => Disguise;
public string Rest => Patrol;
public IReadOnlyList<string> States => StatesArray;
public void Declare(BrainBuilder b)
{
AiStateFragments.Locomotion(b, Disguise, _disguiseMode);
AiStateFragments.Locomotion(b, Patrol, _patrolMode);
}
public void Link(BrainBuilder b) { } // 无内部边:伪装态单向不可逆
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 92aa888ba3d46244bb0592cd8fd2860e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using BaseGames.AI;
namespace BaseGames.Enemies
{
/// <summary>单一未发现态:站桩(Idle)或单一巡逻(Patrol)。出生态与脱战态是同一个。</summary>
[Serializable]
public sealed class SinglePost : IUnawareModule
{
public const string Post = "Post";
static readonly string[] StatesArray = { Post };
[Tooltip("未发现时的移动模式:Idle=站着不动,Patrol=按配置策略游走")]
[SerializeField] LocomotionMode _mode = LocomotionMode.Patrol;
public SinglePost() { }
public SinglePost(LocomotionMode mode) { _mode = mode; }
public string Entry => Post;
public string Rest => Post;
public IReadOnlyList<string> States => StatesArray;
public void Declare(BrainBuilder b) => AiStateFragments.Locomotion(b, Post, _mode);
public void Link(BrainBuilder b) { } // 单态,无内部边
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 50f6c02637b111f44bbe3eea938871be
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: