diff --git a/Assets/_Game/Scripts/AI/AiState.cs b/Assets/_Game/Scripts/AI/AiState.cs new file mode 100644 index 00000000..20019f7e --- /dev/null +++ b/Assets/_Game/Scripts/AI/AiState.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; + +namespace BaseGames.AI +{ + /// 一个状态:进入/每帧/退出钩子 + 出边转换列表(按优先级有序,首个命中即转)。 + public sealed class AiState + { + public string Name { get; } + public Action OnEnter { get; internal set; } + public Action OnTick { get; internal set; } // (ctx, dt) + public Action OnExit { get; internal set; } + public List Transitions { get; } = new List(); + + public AiState(string name) => Name = name; + } +} diff --git a/Assets/_Game/Scripts/AI/AiState.cs.meta b/Assets/_Game/Scripts/AI/AiState.cs.meta new file mode 100644 index 00000000..0e034bac --- /dev/null +++ b/Assets/_Game/Scripts/AI/AiState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 630a7309ff643a04c9de5cd6ef43ded0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Game/Scripts/AI/Transition.cs b/Assets/_Game/Scripts/AI/Transition.cs new file mode 100644 index 00000000..c87c651b --- /dev/null +++ b/Assets/_Game/Scripts/AI/Transition.cs @@ -0,0 +1,29 @@ +using System; + +namespace BaseGames.AI +{ + /// 一条转换:条件型(Condition 非空)或事件型(Event 非空)。二者互斥。 + public sealed class Transition + { + public string Target { get; } + public Func Condition { get; } // 条件型:pull,按 LOD 频率评估 + public AiSignal? Event { get; } // 事件型:push,收到信号即触发 + public string Label { get; } // 可读标签(显式字符串 / 事件名) + + Transition(string target, Func condition, AiSignal? evt, string label) + { + Target = target; + Condition = condition; + Event = evt; + Label = label; + } + + public static Transition OnCondition(string target, Func condition, string label) + => new Transition(target, condition, null, label); + + public static Transition OnEvent(string target, AiSignal evt) + => new Transition(target, null, evt, "on " + evt); + + public bool IsEvent => Event.HasValue; + } +} diff --git a/Assets/_Game/Scripts/AI/Transition.cs.meta b/Assets/_Game/Scripts/AI/Transition.cs.meta new file mode 100644 index 00000000..3f19c1e6 --- /dev/null +++ b/Assets/_Game/Scripts/AI/Transition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de31e9d8e9d89574196fe5244fbdfb27 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Game/Scripts/AI/TransitionRecord.cs b/Assets/_Game/Scripts/AI/TransitionRecord.cs new file mode 100644 index 00000000..7c7912b2 --- /dev/null +++ b/Assets/_Game/Scripts/AI/TransitionRecord.cs @@ -0,0 +1,19 @@ +namespace BaseGames.AI +{ + /// 一次已发生的转换,供调试器/MCP 自省"最近为何转换"。 + public readonly struct TransitionRecord + { + public readonly string From; + public readonly string To; + public readonly string Trigger; // 条件标签或事件名 + + public TransitionRecord(string from, string to, string trigger) + { + From = from; + To = to; + Trigger = trigger; + } + + public override string ToString() => $"{From} -> {To} : {Trigger}"; + } +} diff --git a/Assets/_Game/Scripts/AI/TransitionRecord.cs.meta b/Assets/_Game/Scripts/AI/TransitionRecord.cs.meta new file mode 100644 index 00000000..c4a6ce15 --- /dev/null +++ b/Assets/_Game/Scripts/AI/TransitionRecord.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58fdd083866686f4e9c0008323c2773d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: