diff --git a/07-Other/AI/AI Agent/UnrealEngine/GitNexus 知识图谱.md b/07-Other/AI/AI Agent/UnrealEngine/GitNexus 知识图谱.md index 4f6e0a3..0d21425 100644 --- a/07-Other/AI/AI Agent/UnrealEngine/GitNexus 知识图谱.md +++ b/07-Other/AI/AI Agent/UnrealEngine/GitNexus 知识图谱.md @@ -411,4 +411,98 @@ repos: 同一页面上给检索工具一个优先级: ``` 1. 当前模块 repo → 2. 领域 Group → 3. 全局 Group → 4. grep 兜底 -``` \ No newline at end of file +``` +--- + +## 模块合并方案:188 模块 → 11 功能组 + +### 方案总览 + +| 组名 | 文件数 | 模块数 | 预计耗时 | +|------|--------|--------|----------| +| Core | 2,063 | 1 | 2-4h | +| Engine | 3,934 | 1 | 4-10h | +| Gameplay | 2,874 | 53 | 2-4h | +| Rendering | 1,962 | 30 | 1-2h | +| UI | 1,194 | 10 | 30-60min | +| AudioSignal | 623 | 21 | 15-30min | +| MediaMovieScene | 1,209 | 17 | 30-60min | +| Networking | 1,214 | 13 | 30-60min | +| PhysicsAnimation | 916 | 20 | 30-60min | +| Platform | 493 | 17 | 10-20min | +| Experimental | 1,397 | 1 | 1-2h | + +### 各组包含模块 + +#### Core (2063 files) +- Core + +#### Engine (3934 files) +- Engine + +#### Gameplay (2874 files, 53 模块) +- CoreUObject, ApplicationCore, AppFramework, Launch, Projects, Serialization +- Json, JsonUtilities, XmlParser, Cbor, CoreOnline, CorePreciseFP +- TypedElementFramework, TypedElementRuntime, FieldNotification, UniversalObjectLocator +- TraceLog, DeveloperSettings, BuildSettings, EngineSettings +- AIModule, NavigationSystem, GameplayTasks, GameplayTags, GameplayDebugger +- Navmesh, MassEntity, StateStream, GameMenuBuilder +- Analytics, AutomationMessages, AutomationTest, AutomationWorker +- StorageServerClient, StorageServerClientDebug, RuntimeAssetCache, InstallBundleManager +- PakFile, SessionServices, SessionMessages, Messaging, MessagingCommon, MessagingRpc +- PreLoadScreen, FriendsAndChat, EngineMessages, CrashReportCore, Instrumentation +- StudioTelemetry, PerfCounters, ClientPilot, ExternalRPCRegistry, Portal +- OodleDataCompression, SandboxFile, StreamingFile, StreamingPauseRendering +- CookOnTheFly, MoviePlayerProxy, NullInstallBundleManager, BlueprintRuntime +- PlatformThirdPartyHelpers, CUDA, RSA, PropertyPath, AutoRTFM, AssetRegistry +- UELibrary, UnrealGame, NNE, Toolbox, SymsLib, VerseCompiler, MathCore, Linux + +#### Rendering (1962 files, 30 模块) +- Renderer, RenderCore, RHI, RHICore, D3D12RHI, VulkanRHI, OpenGLDrv +- NullDrv, ColorManagement, OpenColorIOWrapper +- Datasmith, Interchange, MeshDescription, MeshConversion, MeshConversionEngineTypes +- StaticMeshDescription, SkeletalMeshDescription, MeshUtilitiesCommon, RawMesh +- ImageCore, ImageWrapper, ImageWriteQueue, TextureUtilitiesCommon +- IESFile, MaterialShaderQualitySettings, SynthBenchmark + +#### UI (1194 files, 10 模块) +- Slate, SlateCore, UMG, SlateRHIRenderer, AdvancedWidgets +- SlateNullRenderer, WidgetCarousel, InputCore, InputDevice + +#### AudioSignal (623 files, 21 模块) +- AudioMixer, AudioMixerCore, AudioExtensions, AudioAnalyzer, AudioLink +- AudioCaptureCore, AudioCaptureImplementations, AudioDeviceEnumeration +- AudioPlatformConfiguration, AudioPlatformSupport, RadAudioCodec +- BinkAudioDecoder, SignalProcessing, SoundFieldRendering +- NonRealtimeAudioRenderer, OpusAudioDecoder, VorbisAudioDecoder +- AdpcmAudioDecoder, UEJpegComp, UEWavComp + +#### MediaMovieScene (1209 files, 17 模块) +- Media, MediaAssets, MediaUtils, MoviePlayer, MoviePlayerProxy +- MovieScene, MovieSceneCapture, MovieSceneTracks, AVEncoder, AVIWriter +- LevelSequence, TimeManagement, Overlay, GameplayMediaEncoder +- CinematicCamera, LiveLinkInterface, LiveLinkAnimationCore +- LiveLinkMessageBusFramework + +#### Networking (1214 files, 13 模块) +- Online, Net, Networking, NetworkReplayStreaming, NetworkFile +- NetworkFileSystem, Sockets, WebBrowser, WebBrowserTexture +- PacketHandlers, IPC, CEF3Utils, RewindDebuggerRuntimeInterface + +#### PhysicsAnimation (916 files, 20 模块) +- PhysicsCore, GeometryCore, GeometryFramework, AnimationCore +- AnimGraphRuntime, Landscape, Foliage +- ClothingSystemRuntimeInterface, ClothingSystemRuntimeCommon, ClothingSystemRuntimeNv +- VectorVM, InteractiveToolsFramework, AugmentedReality + +#### Platform (493 files, 17 模块) +- Apple, Android, IOS, Linux, Windows, Unix, Solaris +- EyeTracker, HeadMountedDisplay, VirtualProduction, HardwareSurvey +- InputDevice, MRMesh, Advertising + +#### Experimental (1397 files) +- Experimental + +### Group 配置 + +合并后统一放在 Group 下,跨组查询使用 。 \ No newline at end of file diff --git a/07-Other/AI/AI Agent/UnrealEngine/Graphify测试结果/AIDM_NPC_GAS_分析报告.md b/07-Other/AI/AI Agent/UnrealEngine/Graphify测试结果/AIDM_NPC_GAS_分析报告.md new file mode 100644 index 0000000..f05c12a --- /dev/null +++ b/07-Other/AI/AI Agent/UnrealEngine/Graphify测试结果/AIDM_NPC_GAS_分析报告.md @@ -0,0 +1,565 @@ +# AIDM 项目技术分析报告 + +> 测试用提示词(标准化,两组完全一致) +> 项目:AIDM — UE5.7 修仙 ARPG +> 日期:2026-05-30 + +--- + +# 任务 1:NPC 系统完整架构 + +## 1.1 分级机制(A/B/C 三级) + +NPC 分级体系定义在 `LWSNpcTypes.h:111-219` 和设计文档中: + +| 级别 | 数量 | 跨存档保留 | 模拟深度 | 更新频率 | +|------|------|-----------|---------|---------| +| **A级** | 20~40 | 姓名/外貌/性格/资质永不改变(`IdentitySeedId` 种子驱动) | 完整(情绪/关系/目标/记忆/决策) | 每个时间单位 | +| **B级** | 100~300 | 角色定位保留,人物更换 | 中度(目标/关系/基础决策) | 每2~5个时间单位 | +| **C级** | 数百~上千 | 无 | 轻度(位置/状态/基础反应) | 按需/低频 | + +关键字段:`FLWSNpcData` 中 `Tier`(`ELWSNpcTier`)、`IdentitySeedId`(A级跨存档种子ID)。C→B 涌现升级通过 `InteractionCount` 和 `SignificanceScore` 追踪。 + +## 1.2 决策模型(Utility AI) + +核心文件:`LWSNpcDecisionSystem.h/.cpp` + +**评分公式**(`LWSNpcDecisionSystem.h:19-31`): +``` +BaseScore(a) = Σᵢ NeedRelevance[a][i] × Npc.Needs[i] (i ∈ 6维需求) +PersonalityFactor = f(Temperament, Caution, Morality, a) +GoalFactor = Π(Goal Type → bonus, a) +ScoreWithNoise(a) = BaseScore × PersonalityFactor × GoalFactor + Uniform[0, 0.10] +ChosenAction = argmaxₐ ScoreWithNoise(a) +``` + +**6 维需求**:`Survival / Safety / Social / Power / Resource / Cultivation`,每日衰减(缺乏度↑),存储在 `FLWSNpcData::Needs`(`TArray` 长度固定为6)。 + +**7 种高层 Action**:`Wander / GoHome / Cultivate / SeekResource / Socialize / Flee / Hunt` + +**3 种 Behavior**(执行层翻译): +- `Idle` → 原地不动 +- `Wander` → 6邻居随机跳转(20%概率原地不动) +- `MoveTo` → 贪心1-hop向目标移动 + +**3D 性格**(`LWSNpcPersonalityTypes.h`):`Temperament`(冷→热)、`Caution`(慎→莽)、`Morality`(义→私),影响各 Action 的权重系数。 + +**行为持续性**(设计文档 §八,待实施):承诺期 `MinDuration`、完成判定 `IsFinished`、Need 分摊扣减、Stickiness 黏性、Hysteresis 迟滞、中断保护。 + +## 1.3 与时间系统的关系 + +时间系统定义在 `RPGCommon/Public/Time/RPGGameTimeTypes.h` 和 `RPGGameTimeSubsystem.h`: + +- **日历常量**:12月/年,30天/月,360天/年(`FRPGGameRawTime`) +- **驱动方式**:`URPGGameTimeSubsystem::OnGameTimeChanged` 广播,每次 `DeltaDays > 0` 触发 +- **NPC 模拟入口**:`ULWSNpcSimulationSubsystem::HandleGameTimeChanged` 订阅时间广播 → 按 `DeltaDays` 次调用 `SimulateOneDay()` +- **数据流**: + ``` + GameTimeSubsystem.OnGameTimeChanged (DeltaDays>0) + → NpcSim.SimulateDays(N) + → 对每个存活 NPC: + → DecisionSystem.DecayNeeds (需求衰减) + → DecisionSystem.DecideAction (评分→选Action→翻译Behavior) + → TickNpcOneDay (Idle/Wander/MoveTo 物理推进) + → SpatialIndex.Move (更新空间索引) + → PushTrail (环形buffer记录轨迹) + → 同格NPC关系建立 / 关系衰减 / 信息传播 + ``` + +## 1.4 存档方式 + +存档系统定义在 `RPGSaveSystem/Public/RPGSaveSubsystem.h`: + +- **两级存档**:`URPGSaveSystemData`(系统级,槽位列表)+ `URPGSaveDataObject`(玩家级,`TMap`) +- **接口机制**:各模块通过 `ISaveableInterface` 注册到 `URPGSaveSubsystem`,以 `FName SaveID` 标识 +- **NPC 数据持久化**:`ULWSNpcSimulationSubsystem` 提供 `GetActiveNpcsCopy()`(返回 `TArray` 副本)和 `RestoreNpcsFromSave()`(从存档还原),NPC 数据作为 `FLWSNpcData[]` 序列化存入 `FSaveDataContainer` +- **玩家数据持久化**:通过 `URPGAttributeSet` + `FRPGCharacterAttributeData` 保存属性,`FRPGSkilllActionPoseTree` 保存技能映射,`FSkilllTreeDataPool` 保存技能树 + +--- + +# 任务 2:商队 NPC 跨系统依赖分析 + +新增「商队 NPC」类型需要修改以下模块: + +## 必须修改的模块 + +### 1. LivingWorldSystem 模块 + +| 文件 | 修改内容 | +|------|---------| +| `LWSNpcTypes.h` | `ELWSNpcBehavior` 新增 `Trade`/`Caravan` 枚举值;`FLWSNpcData` 新增字段:`TradeRoute`(起点→终点)、`TradeGoods`(货物数组)、`CaravanOwnerFactionId` | +| `LWSNpcPersonalityTypes.h` | `ELWSNpcAction` 新增 `TradeCaravan`;`ELWSNpcNeed` 可能需要新增 `Wealth` 维度;`ELWSNpcGoal` 新增 `TradeGoal` | +| `LWSNpcDecisionSystem.h/.cpp` | `NeedRelevance` 矩阵新增 `TradeCaravan` 行;Personality/Goal 权重新增商队相关因子;`ApplyActionToBehavior` 新增 `TradeCaravan → MoveTo` 翻译逻辑 | +| `LWSNpcSimulationSubsystem.h/.cpp` | `TickNpcOneDay` 新增 Trade 行为处理(沿路线移动、到达后触发交易结算) | +| `LWSNpcGenerator.h/.cpp` | 新增商队生成逻辑(沿贸易路线撒点、分配货物) | +| `LWSNpcRelationSubsystem.h/.cpp` | 商队与聚落/势力的交易关系类型 | +| `LWSNpcSpatialIndex.h` | 如无结构变化则无需修改 | + +### 2. 势力/聚落模块 + +| 文件 | 修改内容 | +|------|---------| +| `LWSFactionTypes.h` | 势力新增贸易路线数据、商队所有权 | +| `LWSSettlementGenerator.h` | 聚落间贸易路线生成(可为商队提供路径) | +| `LWSFactionGenerator.h` | 势力初始化时分配商队 | + +### 3. 世界/资源模块 + +| 文件 | 修改内容 | +|------|---------| +| `LWSResourceGenerator.h` | 商队可携带/交易资源类型定义 | +| `LWSChronicleSubsystem.h` | 商队到达/被劫事件写入编年史 | + +## 存档结构变化 + +**需要变化**:`FLWSNpcData` 新增字段(TradeRoute、TradeGoods 等)会影响序列化。由于 `FLWSNpcData` 是 `USTRUCT` 且直接存储在 `ActiveNpcs`(`TArray`),新增字段后旧存档将不兼容。需要: + +1. 在 `URPGSaveDataObject::VersionMap` 中递增 NPC 数据版本号 +2. 提供存档迁移逻辑(`RestoreNpcsFromSave` 中检测旧版本并填充默认值) + +**`FRPGCharacterAttributeData` 和 `URPGAttributeSet`**:如果商队不涉及玩家属性变化,这两处不需要修改。 + +## 对 GAS 属性系统的影响 + +**直接影响:无。** GAS 属性系统(`URPGAttributeSet`)当前服务于玩家/Actor 角色的战斗属性,而 LivingWorld NPC 是纯数据 `USTRUCT`,不挂载 `AbilitySystemComponent`。 + +**间接影响(可选扩展)**:如果未来商队 NPC 需要与玩家发生战斗交互(如劫商队),则需要为商队守卫创建 `RPGAICharacter`(Actor),此时会走 GAS 属性系统。但这属于"商队战斗"子功能,不属于商队基础框架。 + +## 涉及文件汇总(约 12 个文件) + +``` +Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcTypes.h +Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcPersonalityTypes.h +Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcDecisionSystem.h +Plugins/RPGGameCore/Source/LivingWorldSystem/Private/LWSNpcDecisionSystem.cpp +Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcSimulationSubsystem.h +Plugins/RPGGameCore/Source/LivingWorldSystem/Private/LWSNpcSimulationSubsystem.cpp +Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcGenerator.h +Plugins/RPGGameCore/Source/LivingWorldSystem/Private/LWSNpcGenerator.cpp +Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcRelationSubsystem.h +Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSFactionTypes.h +Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSSettlementGenerator.h +Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSChronicleSubsystem.h +``` + +--- + +# 任务 3:「御剑飞行」ActionPose 代码生成 + +## 3.1 枚举扩展 + +在 `RPGTypes.h:202-260` 的 `ELM_ActionPose` 中,`AirFlying` 已存在,但「御剑飞行」作为一种特殊的战斗移动姿态,建议新增专用枚举值: + +```cpp +// RPGTypes.h — 在 AirFlying 之后、AirDodge 之前新增 + +UENUM(BlueprintType) +enum class ELM_ActionPose : uint8 +{ + // ... 现有值保持不变 ... + + //空行 + AirFlying, + //御剑飞行(战斗移动态,可在飞行中施法/攻击) + AirSwordFlying, // <-- 新增 + //空避 + AirDodge, + // ... +}; +``` + +## 3.2 头文件声明 + +```cpp +// SwordFlyingActionPose.h +#pragma once + +#include "CoreMinimal.h" +#include "LogicStateMachine/SDHGAState.h" +#include "GameplayTagContainer.h" +#include "SwordFlyingActionPose.generated.h" + +/** + * 御剑飞行 ActionPose 状态 + * + * 设计要点: + * - 继承自 USDHGAState,挂载在 USkillSMInstance 状态机中 + * - 进入此状态时:角色踩上飞剑,移动速度切换为飞行速度,消耗法力 + * - 在此状态中:可施放子架势技能(SubPose0~5),如御剑冲刺、御剑斩击 + * - 退出此状态时:飞剑消散,恢复地面移动速度 + * - 法力耗尽或受到重击时强制退出 + */ +UCLASS(Blueprintable, BlueprintType) +class RPGGAMEPLAYABILITY_API USwordFlyingActionPoseState : public USDHGAState +{ + GENERATED_BODY() + +public: + USwordFlyingActionPoseState(); + + // Begin USDHGAState + virtual void OnEnterState(const FGameplayTagContainer& ContextTags) override; + virtual void OnExitState(const FGameplayTagContainer& ContextTags) override; + virtual void TickState(float DeltaTime) override; + // End USDHGAState + + // 御剑飞行专属 GameplayEffect(持续消耗法力、修改移动速度) + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "SwordFlying") + TSubclassOf SwordFlyingGE; + + // 法力每秒消耗量 + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "SwordFlying", meta = (ClampMin = "0")) + float ManaCostPerSecond = 5.0f; + + // 飞行移动速度倍率(基于基础 MoveSpeed) + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "SwordFlying", meta = (ClampMin = "1.0")) + float FlightSpeedMultiplier = 1.5f; + + // 受击时是否强制退出御剑 + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "SwordFlying") + bool bForceExitOnHit = true; + + // 最小法力阈值(低于此值强制退出) + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "SwordFlying", meta = (ClampMin = "0")) + float MinManaThreshold = 10.0f; + +protected: + // 进入时应用的 GE Handle(用于退出时移除) + FActiveGameplayEffectHandle ActiveFlyingGEHandle; + + // 检查是否满足持续飞行条件 + bool CanSustainFlying() const; + + // 获取 OwningCharacter 的属性集 + class URPGAttributeSet* GetOwnerAttributeSet() const; +}; +``` + +## 3.3 关键逻辑实现 + +```cpp +// SwordFlyingActionPose.cpp +#include "SwordFlyingActionPose.h" +#include "Character/RPGCharacterBase.h" +#include "Character/Attribute/RPGAttributeSet.h" +#include "Abilities/RPGAbilitySystemComponent.h" +#include "LogicStateMachine/SDHSkillStateMachine.h" + +USwordFlyingActionPoseState::USwordFlyingActionPoseState() +{ + ManaCostPerSecond = 5.0f; + FlightSpeedMultiplier = 1.5f; + bForceExitOnHit = true; + MinManaThreshold = 10.0f; +} + +void USwordFlyingActionPoseState::OnEnterState(const FGameplayTagContainer& ContextTags) +{ + Super::OnEnterState(ContextTags); + + ARPGCharacterBase* Owner = Cast(GetOuterActor()); + if (!Owner) return; + + URPGAbilitySystemComponent* ASC = Owner->GetRPGAbilitySystemComponent(); + URPGAttributeSet* AttrSet = GetOwnerAttributeSet(); + if (!ASC || !AttrSet) return; + + // 1. 应用御剑飞行 GE(持续消耗法力 + 移动速度修改) + if (SwordFlyingGE) + { + FGameplayEffectContextHandle Context = ASC->MakeEffectContext(); + FGameplayEffectSpecHandle Spec = ASC->MakeOutgoingSpec(SwordFlyingGE, 1.0f, Context); + if (Spec.IsValid()) + { + ActiveFlyingGEHandle = ASC->ApplyGameplayEffectSpecToSelf(*Spec.Data.Get()); + } + } + + // 2. 标记角色进入御剑飞行状态 + AttrSet->RPGFlags.AddTag(FGameplayTag::RequestGameplayTag(TEXT("State.ActionPose.SwordFlying"))); + + // 3. 播放踩剑动画 / 飞剑视觉效果(此处接入动画蓝图和 Niagara) + // Owner->PlayMontageSection(...); +} + +void USwordFlyingActionPoseState::OnExitState(const FGameplayTagContainer& ContextTags) +{ + ARPGCharacterBase* Owner = Cast(GetOuterActor()); + if (!Owner) return; + + URPGAbilitySystemComponent* ASC = Owner->GetRPGAbilitySystemComponent(); + URPGAttributeSet* AttrSet = GetOwnerAttributeSet(); + if (!ASC || !AttrSet) return; + + // 1. 移除御剑飞行 GE + if (ActiveFlyingGEHandle.IsValid()) + { + ASC->RemoveActiveGameplayEffect(ActiveFlyingGEHandle); + ActiveFlyingGEHandle = FActiveGameplayEffectHandle(); + } + + // 2. 移除状态 Tag + AttrSet->RPGFlags.RemoveTag(FGameplayTag::RequestGameplayTag(TEXT("State.ActionPose.SwordFlying"))); + + // 3. 恢复地面姿态 → GroundDefault + USkillSMInstance* SkillSM = Owner->GetSkillSMInstance(); + if (SkillSM) + { + SkillSM->SetDynamicSkillByActionPose( + SkillSM->GetDynamicSkillClassByActionPose(ELM_ActionPose::GroundDefault, ELM_SubActionPose::NotSubPose), + ELM_ActionPose::GroundDefault, + ELM_SubActionPose::NotSubPose + ); + } + + Super::OnExitState(ContextTags); +} + +void USwordFlyingActionPoseState::TickState(float DeltaTime) +{ + Super::TickState(DeltaTime); + + // 检查持续飞行条件 + if (!CanSustainFlying()) + { + // 法力不足或生命值危险 → 强制退出 + USkillSMInstance* SkillSM = Cast(GetStateMachineInstance()); + if (SkillSM) + { + SkillSM->ConsumeCommandTransmitter( + FGameplayTag::RequestGameplayTag(TEXT("SkillTransmitter.QuitState.ForceGround")) + ); + } + } +} + +bool USwordFlyingActionPoseState::CanSustainFlying() const +{ + URPGAttributeSet* AttrSet = GetOwnerAttributeSet(); + if (!AttrSet) return false; + + // 法力不足 + if (AttrSet->GetMana() < MinManaThreshold) return false; + + // 生命值过低 + if (AttrSet->GetHealth() <= 0.0f) return false; + + return true; +} + +URPGAttributeSet* USwordFlyingActionPoseState::GetOwnerAttributeSet() const +{ + ARPGCharacterBase* Owner = Cast(GetOuterActor()); + if (!Owner) return nullptr; + + URPGAbilitySystemComponent* ASC = Owner->GetRPGAbilitySystemComponent(); + if (!ASC) return nullptr; + + return const_cast( + ASC->GetSet() + ); +} +``` + +## 3.4 注册到 ActionPoseTree + +在 `SystemData.h:113-134` 的 `FRPGSkilllActionPoseTree` 中注册: + +```cpp +// 玩家学习御剑飞行技能时: +ActionPoseTree.SetActionPoseSkillClass( + FLMActionPose(ELM_ActionPose::AirSwordFlying, ELM_SubActionPose::NotSubPose), + SwordFlyingSkillSMClass +); +``` + +--- + +# 任务 4:「符修」技能效果系统设计 → GAS Effect 映射 + +## 4.1 符修核心机制回顾 + +来自 `修仙流派.md`: + +- **符修定位**:将法术预先封存于符纸,战斗中瞬发不消耗灵力,但一次性使用 +- **加成流派**:魔修、鬼修、音修制符时产出 +20% +- **道艺等级**:Lv.0~Lv.5(未入门→登峰造极),Lv.3+ 生效流派加成 +- **产出**:攻击符、防御符、遁术符、控制符、召唤符 + +## 4.2 符箓类型 → GAS Effect 映射 + +### 类型 A:攻击符(Instant GameplayEffect) + +``` +攻击符 = UGameplayEffect (DurationPolicy = Instant) + ├── Modifiers: + │ ├── Attribute = RPGAttributeSet.Damage (Magnitude = SetByCaller, Tag = "Data.Talisman.Damage") + │ └── Execution = URPGDamageExecution (复用现有伤害结算) + ├── SetByCaller Magnitudes: + │ ├── Data.Damage.Base = 符纸基础伤害 + │ ├── Data.Damage.Bonus = 符修加成百分比 + │ └── Data.Damage.Tough = 韧性伤害 + └── GameplayTags: + ├── GrantedTags: Effect.Damage.Talisman + └── AssetTags: SkillType.Talisman.Attack +``` + +### 类型 B:防御符(Duration GameplayEffect — 有限时间 Buff) + +``` +防御符 = UGameplayEffect (DurationPolicy = HasDuration, Duration = 符纸时长) + ├── Modifiers: + │ ├── Attribute = RPGAttributeSet.Shield (ModifierOp = Additive, 护盾值增加) + │ ├── Attribute = RPGAttributeSet.DefensePower (ModifierOp = Multiplicitive, 防御力+%) + │ └── Attribute = RPGAttributeSet.BlockRate (ModifierOp = Additive, 格挡率+N%) + └── GameplayTags: + ├── GrantedTags: State.Buff.Talisman.Defense + └── AssetTags: SkillType.Talisman.Defense +``` + +### 类型 C:遁术符(Instant + Duration 混合) + +``` +遁术符 = 两段式: + 1) Instant GE: 瞬移(位置修改,走 GameplayCue 或直接 SetActorLocation) + 2) Duration GE: 移速加成 + 闪避率提升(持续 N 秒) + ├── Modifiers: + │ ├── Attribute = RPGAttributeSet.MoveSpeed (Multiplicitive, +x%) + │ └── Attribute = RPGAttributeSet.DodgeRate (Additive, +y%) + └── Tags: State.Buff.Talisman.Escape +``` + +### 类型 D:控制符(Duration GameplayEffect — 施加于目标) + +``` +控制符 = UGameplayEffect (DurationPolicy = HasDuration, 施加于 Enemy ASC) + ├── Modifiers: + │ ├── Attribute = RPGAttributeSet.MoveSpeed (Multiplicitive, -x%, 减速) + │ └── Attribute = RPGAttributeSet.AttackPower (Multiplicitive, -y%, 降攻) + └── GameplayTags: + ├── GrantedTags: State.Debuff.Talisman.Snare (定身/减速) + └── AssetTags: SkillType.Talisman.Control +``` + +### 类型 E:召唤符(Infinite Duration GameplayEffect) + +``` +召唤符 = UGameplayEffect (DurationPolicy = Infinite) + ├── 触发 GameplayCue → 生成召唤物 Actor + ├── Granted Abilities: 召唤物专属技能(如傀儡自动攻击) + └── Tags: State.Buff.Talisman.Summon +``` + +## 4.3 符箓消耗机制 + +符箓作为一种**可消耗物品**而非技能冷却资源: + +```cpp +// FTalismanItemData — 符箓道具数据结构 +USTRUCT(BlueprintType) +struct FTalismanItemData +{ + GENERATED_BODY() + + // 符箓等级(对应道艺等级 Lv.1~5) + UPROPERTY(EditAnywhere, BlueprintReadWrite) + int32 TalismanLevel = 1; + + // 对应的 GameplayEffect Class + UPROPERTY(EditAnywhere, BlueprintReadWrite) + TSubclassOf EffectClass; + + // 符箓所属大道属性(决定伤害/效果类型标签) + UPROPERTY(EditAnywhere, BlueprintReadWrite) + ERPGElementType DaoElement = ERPGElementType::SRT_Fire; + + // 使用符箓 → ApplyGameplayEffectToTarget/Self → 从背包移除 1 张 → 触发 OnTalismanUsed +}; +``` + +**关键设计差异**:符箓不是通过 GAS Ability 释放,而是通过**物品系统 Apply Effect**——这确保了"不消耗灵力"的设计意图,因为 `UGameplayEffect` 的 `Cost` 策略可以为空。 + +## 4.4 符修专属 GameplayTag 体系 + +``` +SkillType.Talisman.Attack // 攻击符 +SkillType.Talisman.Defense // 防御符 +SkillType.Talisman.Escape // 遁术符 +SkillType.Talisman.Control // 控制符 +SkillType.Talisman.Summon // 召唤符 + +Effect.Damage.Talisman // 符箓伤害来源标记 +State.Buff.Talisman.Defense // 符箓防御 Buff +State.Buff.Talisman.Escape // 符箓遁术 Buff (MoveSpeed/Dodge) +State.Debuff.Talisman.Snare // 符箓减速 Debuff +State.Buff.Talisman.Summon // 符箓召唤 Buff + +DaoElement.Fire.Talisman // 火系符箓 +DaoElement.Water.Talisman // 水系符箓 +// ... 按大道属性细分 + +Profession.Talisman.Specialist // 符修身份标签(挂载到 RPGFlags) +``` + +## 4.5 属性映射汇总 + +| 符修机制 | GAS 组件 | 涉及属性 | +|---------|---------|---------| +| 攻击符 | `Instant GE` + `URPGDamageExecution` | Damage, AttackPowerMin/Max, FatalRate, ElementFire... | +| 防御符 | `Duration GE` | Shield, DefensePower, BlockRate | +| 遁术符 | `Instant GE` (位移) + `Duration GE` | MoveSpeed, DodgeRate | +| 控制符 | `Duration GE` (施加目标) | MoveSpeed (减益), AttackPower (减益) | +| 召唤符 | `Infinite GE` + `GameplayCue` | — (生成 Actor) | +| 符纸消耗 | 物品系统 `URPGItemDataAsset` | — (从背包移除) | +| 制符加成 | `CraftingSkillData` + Modifier | 产出数量 ×1.2(流派加成) | +| 符修身份 | `RPGFlags` GameplayTag | `Profession.Talisman.Specialist` | + +**核心洞察**:符修的 GAS 映射极简——不需要自定义 `ExecutionCalculation`,不需要新建 `AttributeSet`,不需要修改 `SDHGameplayAbility`。它完全依赖现有的 `UGameplayEffect` + `GameplayTag` + 物品系统三层即可实现,是十个修仙流派中与现有 GAS 架构耦合度最低的一个。 + +--- + +# 附录:项目关键文件索引 + +## 架构文档 + +| 文件 | 说明 | +|------|------| +| `.trae/documents/02_程序架构/spec.md` | 总体架构(表现层/游戏逻辑/核心框架/引擎) | +| `.trae/documents/02_程序架构/spec_modules.md` | 模块详细规格 | +| `.trae/specs/LivingWorldSystem/spec.md` | LivingWorld 系统完整规格 | + +## NPC 系统 + +| 文件 | 说明 | +|------|------| +| `.trae/documents/01_策划设计/NPC系统与势力/NPC系统设计.md` | NPC 模拟系统完整设计 | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcTypes.h` | NPC 数据结构(FLWSNpcData) | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcPersonalityTypes.h` | 性格/目标/秘密/Need/Action 定义 | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcSimulationSubsystem.h` | 模拟主循环 | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcDecisionSystem.h` | 决策系统(Utility AI) | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcRelationSubsystem.h` | 关系网络 | + +## GAS / 属性系统 + +| 文件 | 说明 | +|------|------| +| `Plugins/RPGGameCore/Source/RPGGameplayAbility/Public/Character/Attribute/RPGAttributeSet.h` | 单一属性容器(5子集) | +| `Plugins/RPGGameCore/Source/RPGGameplayAbility/Public/Character/Attribute/RPGAttributeData.h` | ERPGPhase 境界枚举、灵根 | +| `Plugins/RPGGameCore/Source/RPGGameplayAbility/Public/Config/RPGDamageExecution.h` | GAS 伤害结算 | +| `Plugins/RPGGameCore/Source/RPGGameplayAbility/Public/Abilities/SDHGameplayAbility.h` | 技能基类 | + +## ActionPose / 技能系统 + +| 文件 | 说明 | +|------|------| +| `Plugins/RPGGameCore/Source/RPGGameplayAbility/Public/RPGTypes.h` | ELM_ActionPose 枚举、FLMActionPose | +| `Plugins/RPGGameCore/Source/RPGGameplayAbility/Public/System/SystemData.h` | FRPGSkilllActionPoseTree | +| `Plugins/RPGGameCore/Source/RPGGameplayAbility/Public/LogicStateMachine/SDHSkillStateMachine.h` | 技能状态机 | + +## 修仙设计文档 + +| 文件 | 说明 | +|------|------| +| `.trae/documents/01_策划设计/修仙基础概念设定/修仙概念体系.md` | 流派/道艺/大道属性三层体系 | +| `.trae/documents/01_策划设计/修仙基础概念设定/修仙流派.md` | 十大流派详细设计 | +| `.trae/documents/01_策划设计/修仙基础概念设定/大道元素属性.md` | 37种大道属性 | diff --git a/07-Other/AI/AI Agent/UnrealEngine/Graphify测试结果/AIDM_NPC与修仙系统分析报告_Graphify.md b/07-Other/AI/AI Agent/UnrealEngine/Graphify测试结果/AIDM_NPC与修仙系统分析报告_Graphify.md new file mode 100644 index 0000000..ab54cd4 --- /dev/null +++ b/07-Other/AI/AI Agent/UnrealEngine/Graphify测试结果/AIDM_NPC与修仙系统分析报告_Graphify.md @@ -0,0 +1,814 @@ +# AIDM 项目测试分析报告 + +> 生成日期:2026-05-30 +> 项目:D:\MatrixTA\AIGameDev\AIDM +> 基于:LivingWorldSystem Spec、ARPGGameDevelopment Research Report、修仙流派设计文档 + +--- + +[TOC] + +--- + +## 任务 1:NPC 系统完整架构 + +### 一、分级机制 + +项目采用 **三层 NPC 分级模型**(来自 `rationale_npc_tier_abc` 超边): + +| 级别 | 名称 | 特征 | 数据承载 | +|------|------|------|----------| +| **A 级** | 核心 NPC(玩家、重要角色) | 完整 3D Actor、行为树、动画、GAS 属性 | `ARPGCharacterBase` + `URPGAbilitySystemComponent` | +| **B 级** | 势力 NPC(宗门弟子、城镇守卫) | 轻量 Actor + 基础动画,结合纯数据模拟 | `ARPGAICharacter` + 部分 `FLWSNpcData` 字段 | +| **C 级** | 泛 NPC(平民、路人、妖兽) | **纯数据 USTRUCT**,无 Actor,不走 NavMesh,六边形坐标跳转 | `FLWSNpcData`(位于 `LWSNpcTypes.h`) | + +分级依据文档 `00_项目总控/游戏核心创意.md` 中的"NPC锚点和分级"概念,结合 `LivingWorldSystem Spec` 中明确的"NPC 纯数据模拟"策略。 + +### 二、决策模型 + +**核心架构:Utility AI + 性格权重 + 目标驱动** + +``` +每个 NPC 每日 Tick: + ┌────────────────────────────────────────────┐ + │ ULWSNpcSimulationSubsystem (UWorldSubsystem) │ + │ ├─ 订阅 URPGGameTimeSubsystem::OnGameTimeChanged │ + │ ├─ SimulateDays(DeltaDays) │ + │ └─ 每日遍历 ActiveNpcs │ + └──────────────┬─────────────────────────────┘ + │ + ▼ + ┌────────────────────────────────────────────┐ + │ ULWSNpcDecisionSystem (决策引擎) │ + │ ├─ DecayNeeds() — 需求自然衰减(生存↑/安全↑/社交↑...) │ + │ ├─ ScoreAction() — 对所有可能行为打分 │ + │ │ ├─ 当前需求值 × 行为匹配度 │ + │ │ └─ 性格权重因子 PersonalityFactor │ + │ └─ ApplyActionToBehavior() — 选最高分执行 │ + └──────────────┬─────────────────────────────┘ + │ + ▼ + ELWSNpcAction { Idle, Wander, MoveTo, Trade, Fight, Socialize, Cultivate, ... } +``` + +**性格三维度**(`FLWSNpcPersonality`,位于 `LWSNpcPersonalityTypes.h`): + +- **冷 ↔ 热**:影响社交行为权重 +- **慎 ↔ 莽**:影响战斗/探索行为权重 +- **私 ↔ 义**:影响帮助盟友 vs 追求私利 + +**需求六维度**(`ELWSNpcNeed`):生存、安全、社交、权力、资源、修炼 + +**决策实现位置**: + +- `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcDecisionSystem.h` +- `Plugins/RPGGameCore/Source/LivingWorldSystem/Private/LWSNpcDecisionSystem.cpp` + +### 三、与时间系统的关系 + +**时间模型:回合+实时混合制,日为原子单位**(Community 15:策划世界系统) + +``` +URPGGameTimeSubsystem (UGameInstanceSubsystem,跨 World 持续) + │ + ├─ FSDHGameRawTime / FSDHGameTime (30天/月, 12月/年) + ├─ OnGameTimeChanged 委托广播 + ├─ 世界时间推进 → AddGameTime(DeltaDays) + │ + └──→ ULWSNpcSimulationSubsystem::SimulateDays(DeltaDays) + ├─ 每日遍历所有 NPC + ├─ Wander 算法(WanderStayProbability 概率不动,否则随机六邻一步) + ├─ 调用决策系统 DecideAction + └─ 缓存轨迹(环形 buffer 32 步) +``` + +**关键时间常量**: + +- 1 日 = 最小原子单位 +- 2 帧完成一轮完整 NPC 模拟(60 FPS 下每帧处理 1/30 NPC) +- NPC 模拟在**后台线程**批量执行 + +### 四、存档方式 + +**双层存档架构**(Community 5 + Community 15): + +``` +第一层:世界永久层(跨存档持久化) + │ + ├─ LWSWorldSaveGame (USaveGame 子类) + │ ├─ CachedTileCoords / TileBuffer → 瓦片数据 + │ ├─ CachedRivers / CachedLakes → 水文数据 + │ ├─ CachedFactions → 势力数据 + │ ├─ CachedNpcs → NPC 数据 (TArray) + │ ├─ CachedSpiritualVeins → 灵脉数据 + │ └─ CachedSettlements / Resources → 聚落/资源数据 + │ + └─ 世界编年史(跨存档的人生记录,待阶段二实现) + +第二层:角色存档层(可删除/重建) + │ + └─ URPGPlayerSaveGame + ├─ RPGAttributeData → FRPGCharacterAttributeData + ├─ SkillTreeDataPool → 技能树学习状态 + ├─ RPGSkilllActionPoseTree → 架势-技能装配绑定 + ├─ RPGItemDataMap → 物品容器数据 + └─ TalentComponentSaveData → 天赋数据 +``` + +**存档关键实现**: + +- `ALWSWorldGenerator::SaveWorld()` 写入 `ULWSWorldSaveGame`(蓝图可调用) +- `ALWSWorldGenerator::LoadWorld()` 从存档完整还原世界 +- NPC 数据通过 `ULWSNpcSimulationSubsystem::GetActiveNpcsCopy()` / `RestoreNpcsFromSave()` 同步 +- **角色存档删除后,世界永久层不受影响**——势力变迁、NPC 死亡/成长、资源消耗写入世界层 + +--- + +## 任务 2:新增「商队 NPC」跨系统依赖分析 + +### 一、需要修改的模块及文件 + +#### 1. NPC 数据结构层(核心修改) + +| 文件 | 修改内容 | +|------|---------| +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcTypes.h` | `FLWSNpcData` 新增字段:`TradeRouteIndex`(商队路线 ID)、`TradeGoods`(货物数组 TMap)、`TradeFactionOrigin`/`TradeFactionDestination`(起止势力)、`TradeSpeed`(行进速度,单位 hex/日) | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcPersonalityTypes.h` | 新增 `ELWSNpcBehavior::Trade` 行为枚举值;新增 `ELWSNpcRole::CaravanTrader` 角色类型 | + +#### 2. 行为/决策系统 + +| 文件 | 修改内容 | +|------|---------| +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcDecisionSystem.h` | `DecideAction()` 新增商队逻辑:到达目的地时触发交易结算、反向切换目的地 | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Private/LWSNpcDecisionSystem.cpp` | 实现 `ScoreAction_Trade()`:需求权重(资源需求×商队距离评分) | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcSimulationSubsystem.h` | `SimulateDays()` 新增商队每日推进:沿 A* 路径逐格移动(有别于 Wander 随机) | + +#### 3. 势力与生成 + +| 文件 | 修改内容 | +|------|---------| +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSNpcGenerator.h/.cpp` | `GenerateNpcs()` 新增商队生成逻辑:势力边界间配对生成商队 NPC,泊松碟约束 + 路线预计算 | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSFactionTypes.h` | `FLWSFaction` 新增 `TradePartners`(贸易伙伴势力 ID 列表)、`TradeRouteFrequencies`(每条路线商队生成频率) | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Private/LWSFactionGenerator.cpp` | 势力生成后自动配对邻近势力建立贸易路线 | + +#### 4. 寻路系统 + +| 文件 | 修改内容 | +|------|---------| +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSPathfinder.h` | 商队寻路需在 `FLWSPathfindingParams` 中支持路线成本(避开高危势力区、倾向道路/平原) | + +#### 5. 存档 + +| 文件 | 修改内容 | +|------|---------| +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSWorldSaveGame.h` | `FLWSNpcData` 新增字段会自然序列化;新增 `CachedTradeRoutes`(`TArray` 路线拓扑数据) | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSTradeTypes.h` | **新建**:`FLWSTradeGoods`(物品 ID + 数量)、`FLWSTradeRoute`(起始势力、途经 hex 坐标数组、路线等级) | + +#### 6. 调试可视化 + +| 文件 | 修改内容 | +|------|---------| +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Private/LWSWorldGenerator.cpp` | 新增 `DebugDrawTradeRoutes()`:商队路线以黄色虚线绘制;商队位置以金色圆点标记 | +| `Plugins/RPGGameCore/Source/LivingWorldSystem/Public/LWSResourceTypes.h` | `ELWSDebugViewMode` 新增 `TradeRoutes` 枚举 | + +### 二、存档结构变化 + +**不需要破坏性变更**。`FLWSNpcData` 的字段扩展会被 UE 序列化自动兼容(USTRUCT 标记 UPROPERTY 的字段)。需要新增: + +```cpp +// 新建 LWSTradeTypes.h +USTRUCT() +struct FLWSTradeRoute +{ + UPROPERTY() int32 RouteId; + UPROPERTY() int32 OriginFactionId; + UPROPERTY() int32 DestinationFactionId; + UPROPERTY() TArray Waypoints; // A* 预计算路径 + UPROPERTY() float RouteLevel; // 路线等级(影响货物品质) +}; + +// LWSWorldSaveGame 新增 +UPROPERTY() TArray CachedTradeRoutes; +``` + +**双层存档不受影响**:商队 NPC 属于 `CachedNpcs`(世界永久层),角色存档删除不影响商队。 + +### 三、对 GAS 属性系统的影响 + +**不影响 GAS 属性系统。** 原因: + +1. 商队 NPC 是**纯数据 C 级 NPC**(`FLWSNpcData`),不持有 `URPGAbilitySystemComponent`,不参与 GAS Attribute 同步 +2. 商队交易结算是**数值运算**(货物价值 = 距离 × 势力稀缺度 × 路线等级),不涉及战斗伤害管线 +3. 如果未来需要"商队被劫掠"战斗,才需要通过 C→B 级 NPC 升级机制接入 GAS + +--- + +## 任务 3:为「御剑飞行」新增 ActionPose + +### 设计分析 + +当前 `ELM_ActionPose` 已有 `AirFlying`(空行)作为通用空中飞行态,但**御剑飞行**是剑修专属的战斗力+移动融合态:站在飞剑上高速移动,可在飞行中发起剑技攻击。需要作为独立主架势加入。 + +**状态流转:** + +``` +地面起势 (GroundDefault) + │ 释放御剑飞行技能 + ▼ +御剑飞行 (AirSwordFlight) ← 新增 + │ + ├── 输入方向 → 高速移动(飞行移动速度 ×2.5) + ├── 左键 (SubPose0) → 飞剑斩(空中剑技连段) + ├── 右键 (SubPose1) → 剑罡护体 + ├── 闪避键 → 御剑急转 (AirSwordFlight → AirDash) + │ + ├── 耐力耗尽/被击落 → AirFalling + └── 主动取消/落地 → GroundLanding +``` + +### 1. RPGTypes.h — 新增枚举值 + +```cpp +// RPGTypes.h — 在 ELM_ActionPose 枚举中 AirDash 之后插入 +enum class ELM_ActionPose : uint8 +{ + // ... 现有值不变 ... + AirDash, // 空冲(飞行状态下的快速冲击) + + // === 御剑飞行(新增)=== + AirSwordFlight, // 御剑飞行态:剑修站在飞剑上高速移动+空中战斗 + + AirSpring, // 空遁 + // ... 后续值不变 ... +}; +``` + +### 2. RPGSwordFlightAbility.h — 御剑飞行 GA 头文件(新建) + +```cpp +// Plugins/RPGGameCore/Source/RPGGameplayAbility/Public/Abilities/RPGSwordFlightAbility.h + +#pragma once + +#include "SDHGameplayAbility.h" +#include "GameplayTagContainer.h" +#include "RPGSwordFlightAbility.generated.h" + +class AWeaponBase; +class UNiagaraSystem; +class UGameplayEffect; + +/** + * 御剑飞行 GameplayAbility + * Lifecycle: ActivateAbility → UpdateAbility(每帧) → EndAbility + * 角色站在飞剑上进入 AirSwordFlight 架势,高速飞行 + 空中剑技 + */ +UCLASS(BlueprintType, Blueprintable) +class RPGGAMEPLAYABILITY_API URPGSwordFlightAbility : public URPGGameplayAbility +{ + GENERATED_BODY() + +public: + URPGSwordFlightAbility(); + + virtual void ActivateAbility() override; + virtual void UpdateAbility(float DeltaTime) override; + virtual void EndAbility() override; + + // === 配置属性 === + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "SwordFlight|Movement") + float FlightSpeed = 2000.f; // 基础飞行速度 (cm/s) + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "SwordFlight|Movement") + float MaxAcceleration = 3000.f; // 最大加速度 + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "SwordFlight|Movement") + float TurnRate = 180.f; // 转向速率 (deg/s) + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "SwordFlight|Resource") + float ManaDrainPerSecond = 8.f; // 每秒法力消耗 + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "SwordFlight|Resource") + float MinManaToActivate = 30.f; // 最低法力阈值(低于此值强制解除) + + // === 视觉 === + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "SwordFlight|Visual") + TSubclassOf SwordFlightActorClass; // 飞剑 Actor(附着到角色脚下) + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "SwordFlight|Visual") + UNiagaraSystem* FlightTrailEffect; // 飞行拖尾 Niagara 特效 + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "SwordFlight|Visual") + FRotator SwordMountRotation = FRotator(0.f, 0.f, 15.f); // 飞剑倾斜角度 + + // === GAS Effect === + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "SwordFlight|Effects") + TSubclassOf SwordFlightMovementGE; // 修改 MoveSpeed、GravityScale + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "SwordFlight|Effects") + TSubclassOf SwordFlightDamageBonusGE; // 飞剑期间剑技伤害 +25% + + // === 蓝图事件 === + UFUNCTION(BlueprintImplementableEvent, Category = "SwordFlight") + void OnSwordMounted(AActor* SwordActor); + + UFUNCTION(BlueprintImplementableEvent, Category = "SwordFlight") + void OnSwordDismounted(); + + UFUNCTION(BlueprintImplementableEvent, Category = "SwordFlight") + void OnFlightManaDepleted(); // 法力耗尽事件 + +private: + // === 内部状态 === + UPROPERTY() + TObjectPtr MountedSword; // 当前挂载的飞剑 Actor + + UPROPERTY() + TObjectPtr TrailNiagara; // 拖尾特效组件 + + UPROPERTY() + FActiveGameplayEffectHandle MovementGEHandle; // 移动 GE 句柄 + + UPROPERTY() + FActiveGameplayEffectHandle DamageBonusHandle; // 伤害加成 GE 句柄 + + bool bIsActive = false; + float CurrentManaDrainAccum = 0.f; // 法力消耗累加器 + + // --- 内部方法 --- + void SpawnAndMountSword(); + void ApplyFlightEffects(); + void RemoveFlightEffects(); + bool CheckManaSufficient() const; + void DrainManaPerTick(float DeltaTime); +}; +``` + +### 3. RPGSwordFlightAbility.cpp — 关键逻辑实现(核心) + +```cpp +// Plugins/RPGGameCore/Source/RPGGameplayAbility/Private/Abilities/RPGSwordFlightAbility.cpp + +#include "Abilities/RPGSwordFlightAbility.h" +#include "Character/RPGCharacterBase.h" +#include "Character/Attribute/RPGAttributeSet.h" +#include "Character/Attribute/RPGAttributeComponent.h" +#include "NiagaraComponent.h" +#include "NiagaraFunctionLibrary.h" +#include "GameFramework/CharacterMovementComponent.h" +#include "AbilitySystemComponent.h" + +URPGSwordFlightAbility::URPGSwordFlightAbility() +{ + // 标记为持续型 Ability(非一次性瞬发) +} + +void URPGSwordFlightAbility::ActivateAbility() +{ + Super::ActivateAbility(); + + ARPGCharacterBase* Owner = Cast(GetSkillUser()); + if (!Owner || !CheckManaSufficient()) + { + SetAbilityValid(false); + return; + } + + // 1. 生成飞剑并挂载到角色脚底 + SpawnAndMountSword(); + + // 2. 应用飞行 GE(修改 CMC MoveSpeed、GravityScale) + ApplyFlightEffects(); + + // 3. 角色进入飞行模式 + if (UCharacterMovementComponent* CMC = Owner->GetCharacterMovement()) + { + CMC->SetMovementMode(MOVE_Flying); + CMC->MaxFlySpeed = FlightSpeed; + CMC->MaxAcceleration = MaxAcceleration; + CMC->BrakingDecelerationFlying = 1000.f; + } + + // 4. 设置架势为 御剑飞行 + if (USkillSMInstance* SM = Owner->GetSkillSMInstance()) + { + SM->SetActionPose(ELM_ActionPose::AirSwordFlight); + } + + // 5. 生成长剑拖尾特效 + if (FlightTrailEffect) + { + TrailNiagara = UNiagaraFunctionLibrary::SpawnSystemAttached( + FlightTrailEffect, + Owner->GetRootComponent(), + NAME_None, + FVector::ZeroVector, + FRotator::ZeroRotator, + EAttachLocation::KeepRelativeOffset, + true + ); + } + + bIsActive = true; + SetAbilityValid(true); +} + +void URPGSwordFlightAbility::UpdateAbility(float DeltaTime) +{ + Super::UpdateAbility(DeltaTime); + if (!bIsActive) return; + + // 法力消耗检查 + DrainManaPerTick(DeltaTime); + if (!CheckManaSufficient()) + { + OnFlightManaDepleted(); + EndAbility(); + return; + } + + // 可选:根据输入方向调整飞剑倾斜 + // 通过蓝图 OnFlightUpdate 事件暴露给设计师微调 +} + +void URPGSwordFlightAbility::EndAbility() +{ + Super::EndAbility(); + + ARPGCharacterBase* Owner = Cast(GetSkillUser()); + if (!Owner) return; + + // 1. 恢复地面移动模式 + if (UCharacterMovementComponent* CMC = Owner->GetCharacterMovement()) + { + CMC->SetMovementMode(MOVE_Walking); + CMC->MaxFlySpeed = 600.f; // 恢复默认 + } + + // 2. 移除 GE + RemoveFlightEffects(); + + // 3. 销毁拖尾 + if (TrailNiagara) + { + TrailNiagara->Deactivate(); + TrailNiagara = nullptr; + } + + // 4. 拆卸飞剑 → 切换到 AirFalling + OnSwordDismounted(); + if (MountedSword) + { + MountedSword->Destroy(); + MountedSword = nullptr; + } + + // 5. 架势切换:御剑 → 空中下落 + if (USkillSMInstance* SM = Owner->GetSkillSMInstance()) + { + SM->SetActionPose(ELM_ActionPose::AirFalling); + } + + bIsActive = false; +} + +// ============ 内部实现 ============ + +void URPGSwordFlightAbility::SpawnAndMountSword() +{ + ARPGCharacterBase* Owner = Cast(GetSkillUser()); + if (!Owner || !SwordFlightActorClass) return; + + FActorSpawnParameters SpawnParams; + SpawnParams.Owner = Owner; + SpawnParams.Instigator = Owner; + + // 飞剑生成在角色脚下 + FVector SpawnLoc = Owner->GetActorLocation() + FVector(0, 0, -70.f); + MountedSword = GetWorld()->SpawnActor( + SwordFlightActorClass, SpawnLoc, FRotator::ZeroRotator, SpawnParams + ); + + if (MountedSword) + { + MountedSword->AttachToComponent( + Owner->GetRootComponent(), + FAttachmentTransformRules::KeepRelativeTransform + ); + MountedSword->SetActorRelativeLocation(FVector(0, 0, -70.f)); + MountedSword->SetActorRelativeRotation(SwordMountRotation); + OnSwordMounted(MountedSword); + } +} + +void URPGSwordFlightAbility::ApplyFlightEffects() +{ + ARPGCharacterBase* Owner = Cast(GetSkillUser()); + if (!Owner) return; + + URPGAbilitySystemComponent* ASC = Owner->GetRPGAbilitySystemComponent(); + if (!ASC) return; + + // 施加飞行移动 GE + if (SwordFlightMovementGE) + { + MovementGEHandle = ASC->ApplyGameplayEffectToSelf( + SwordFlightMovementGE->GetDefaultObject(), + 1.f, ASC->MakeEffectContext() + ); + } + + // 施加伤害加成 GE + if (SwordFlightDamageBonusGE) + { + DamageBonusHandle = ASC->ApplyGameplayEffectToSelf( + SwordFlightDamageBonusGE->GetDefaultObject(), + 1.f, ASC->MakeEffectContext() + ); + } +} + +void URPGSwordFlightAbility::RemoveFlightEffects() +{ + ARPGCharacterBase* Owner = Cast(GetSkillUser()); + if (!Owner) return; + + URPGAbilitySystemComponent* ASC = Owner->GetRPGAbilitySystemComponent(); + if (!ASC) return; + + if (MovementGEHandle.IsValid()) + ASC->RemoveActiveGameplayEffect(MovementGEHandle); + if (DamageBonusHandle.IsValid()) + ASC->RemoveActiveGameplayEffect(DamageBonusHandle); +} + +bool URPGSwordFlightAbility::CheckManaSufficient() const +{ + ARPGCharacterBase* Owner = Cast(GetSkillUser()); + if (!Owner) return false; + + URPGAbilitySystemComponent* ASC = Owner->GetRPGAbilitySystemComponent(); + if (!ASC) return false; + + return ASC->GetNumericAttribute(URPGAttributeSet::GetManaAttribute()) >= MinManaToActivate; +} + +void URPGSwordFlightAbility::DrainManaPerTick(float DeltaTime) +{ + CurrentManaDrainAccum += ManaDrainPerSecond * DeltaTime; + if (CurrentManaDrainAccum >= 1.f) + { + int32 DrainAmount = FMath::FloorToInt(CurrentManaDrainAccum); + CurrentManaDrainAccum -= DrainAmount; + + ARPGCharacterBase* Owner = Cast(GetSkillUser()); + if (Owner) + { + Owner->GetRPGAbilitySystemComponent()->SetNumericAttributeBase( + URPGAttributeSet::GetManaAttribute(), + FMath::Max(0.f, Owner->GetRPGAbilitySystemComponent()-> + GetNumericAttribute(URPGAttributeSet::GetManaAttribute()) - DrainAmount) + ); + } + } +} +``` + +--- + +## 任务 4:「符修」技能效果系统设计(映射到 GAS Effect) + +### 设计前提 + +符修在流派体系中的定位:通过绘制**符文符箓**将法术封印在纸上,战斗中消耗符箓瞬间释放。核心机制是**制符(战前准备)→ 释符(战斗中消耗)**。符文效果通过 GAS GameplayEffect 实现。 + +### 一、符修核心机制数据模型 + +#### FRTalismanData.h(新建) + +```cpp +// Plugins/RPGGameCore/Source/RPGGameplayAbility/Public/Abilities/Talisman/FRTalismanData.h + +#pragma once + +#include "GameplayTagContainer.h" +#include "GameplayEffect.h" +#include "FRTalismanData.generated.h" + +/** 符箓等级 */ +UENUM(BlueprintType) +enum class ERPGTalismanTier : uint8 +{ + YellowPaper UMETA(DisplayName = "黄纸符"), // 基础符,单次效果 + SilverScript UMETA(DisplayName = "银篆符"), // 中级符,可叠加2层 + GoldSeal UMETA(DisplayName = "金印符"), // 高级符,效果翻倍 + JadeEdict UMETA(DisplayName = "玉敕符"), // 顶级符,范围效果 +}; + +/** 符箓触发方式 */ +UENUM(BlueprintType) +enum class ERPGTalismanTrigger : uint8 +{ + OnUse UMETA(DisplayName = "主动释放"), // 主动从快捷栏使用 + OnHit UMETA(DisplayName = "受击触发"), // 被攻击时自动触发 + OnLowHP UMETA(DisplayName = "濒死护身"), // HP < 30% 自动触发 + OnTimer UMETA(DisplayName = "定时触发"), // 定时延迟触发 +}; + +/** 单个符箓效果定义 — 映射到 1 个 GAS GameplayEffect */ +USTRUCT(BlueprintType) +struct RPGGAMEPLAYABILITY_API FRPGTalismanEffect +{ + GENERATED_BODY() + + // 符箓配置 + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Talisman|Identity") + FName TalismanId; // 符箓唯一 ID + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Talisman|Identity") + FText TalismanName; // 显示名:"烈火符"、"金刚符" + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Talisman|Identity") + ERPGTalismanTier Tier = ERPGTalismanTier::YellowPaper; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Talisman|Identity") + ERPGTalismanTrigger TriggerType = ERPGTalismanTrigger::OnUse; + + // === GAS 映射 === + // 核心:每个符箓效果对应一个 UGameplayEffect 蓝图子类 + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Talisman|GAS") + TSubclassOf PrimaryEffectClass; // 主 GE(修改属性/施加 Tag) + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Talisman|GAS") + TSubclassOf SecondaryEffectClass; // 副 GE(可选,范围/连锁效果) + + // SetByCaller 动态参数(符箓等级越高,倍率越大) + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Talisman|GAS") + TMap SetByCallerMagnitudes; // Tag → 基础数值 + + // 消耗 + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Talisman|Cost") + int32 ManaCost = 20; // 释符消耗法力 + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Talisman|Cost") + float CooldownSeconds = 3.f; // 释符冷却 +}; +``` + +### 二、符修五大符系 → GAS GameplayEffect 映射表 + +| 符系 | 代表符箓 | GAS GE 类型 | 修改的 Attribute | Duration Policy | 关键 SetByCaller Tag | +|------|---------|------------|-----------------|-----------------|---------------------| +| **攻击符系** | 烈火符 | `GE_Talisman_Fire` (Instant) | `Damage` (临时变量) | Instant | `SetByCaller.FireDamage` | +| | 冰封符 | `GE_Talisman_Ice` (HasDuration) | `MoveSpeed` (减速 %) | 5s Duration | `SetByCaller.SlowPercent` | +| | 雷击符 | `GE_Talisman_Thunder` (Instant) | `Damage` + `Tough` (削韧) | Instant | `SetByCaller.ThunderDamage` | +| **防御符系** | 金刚符 | `GE_Talisman_Barrier` (HasDuration) | `Shield` (+护盾值) | 10s Duration | `SetByCaller.ShieldAmount` | +| | 铁壁符 | `GE_Talisman_IronWall` (HasDuration) | `DefensePower` (+%) | 15s Duration | `SetByCaller.DefenseBonus` | +| | 净身符 | `GE_Talisman_Cleanse` (Instant) | 移除 `State.Debuff.*` Tag | Instant | — | +| **辅助符系** | 神行符 | `GE_Talisman_Speed` (HasDuration) | `MoveSpeed` (+%) | 20s Duration | `SetByCaller.SpeedBonus` | +| | 聚灵符 | `GE_Talisman_Meditate` (HasDuration) | `Mana` (回复速率) | 30s Duration | `SetByCaller.ManaRegenRate` | +| | 破阵符 | `GE_Talisman_Break` (Instant) | 移除敌方 Buff Tag | Instant | `SetByCaller.DispelCount` | +| **诅咒符系** | 虚弱符 | `GE_Talisman_Weaken` (HasDuration) | `AttackPower` (-%敌方) | 8s Duration | `SetByCaller.AttackReduce` | +| | 定身符 | `GE_Talisman_Root` (HasDuration) | 施加 `State.CrowdControl.Root` Tag | 3s Duration | `SetByCaller.RootDuration` | +| | 噬魂符 | `GE_Talisman_SoulDrain` (HasDuration) | 敌方 `Health` DoT + 自身 `Health` Heal | 6s Duration | `SetByCaller.DrainAmount` | +| **阵法符系** | 困龙阵符 | `GE_Talisman_TrapField` (Infinite/HasDuration) | 范围 `MoveSpeed` -80% | 15s 范围 Duration | `SetByCaller.TrapRadius` | +| | 万剑阵符 | `GE_Talisman_SwordArray` (Instant × N) | 范围内 N 次 `Damage` 结算 | Instant (周期触发) | `SetByCaller.PerSwordDamage` | +| | 回春阵符 | `GE_Talisman_HealField` (Infinite) | 范围内友方 `Health` 持续回复 | UntilCancelled | `SetByCaller.HealPerTick` | + +### 三、与现有 GAS Effect 架构的融合 + +#### 3.1 对接伤害管线 + +符修攻击符接入现有五段伤害管线(来自 Community 5): + +``` +释符(烈火符) + │ URPGGameplayAbility::ActivateAbility() + ├── 构造 FSkillDamageData + │ ├─ SkillDamage = SetByCaller.FireDamage × TierMultiplier + │ ├─ SkillToughDamage = SetByCaller.FireDamage × 0.3 + │ └─ HitLevel = ERPGHitLevel::LV1(黄纸)~ LV3(玉敕) + │ + └── ARPGCharacterBase::ReceiveDamageEvent() + ├── USDHDamageCaculationSetting::CaculateDamage() + │ ├─ 暴击 / 命中 / 闪避 / 防御减伤 + │ └─ 输出 { ShieldDamage, ToughDamage, HealthDamage } + ├── 优先扣 Shield → 再扣 Tough → 最后扣 Health + └── URPGAttributeSet::PostGameplayEffectExecute +``` + +#### 3.2 符箓充能与释放系统 + +```cpp +// URPGFuXiuAbilityComponent — 符修专属 ASC 扩展 +UCLASS() +class URPGFuXiuAbilityComponent : public UActorComponent +{ + // 符箓背包(最多携带 N 张符) + UPROPERTY() + TArray EquippedTalismans; + + // 制符(非战斗状态,消耗材料+法力+时间) + UFUNCTION(BlueprintCallable) + FRPGTalismanEffect CraftTalisman(FName TalismanId, ERPGTalismanTier Tier); + + // 释符(战斗中触发 GAS GE) + UFUNCTION(BlueprintCallable) + bool ActivateTalisman(int32 TalismanIndex, AActor* Target = nullptr); + + // 符箓等级倍率 + float GetTierMultiplier(ERPGTalismanTier Tier) const + { + static const TMap Multipliers = { + { ERPGTalismanTier::YellowPaper, 1.0f }, + { ERPGTalismanTier::SilverScript, 1.5f }, + { ERPGTalismanTier::GoldSeal, 2.2f }, + { ERPGTalismanTier::JadeEdict, 3.0f }, + }; + return Multipliers.FindRef(Tier); + } +}; +``` + +#### 3.3 SetByCaller 符箓 Tag 体系 + +```cpp +// 在 SDHGameTagSettings 中新增符箓专属 SetByCaller Tag +namespace RPGSetByCaller +{ + // 攻击符 + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_Fire_Damage); + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_Ice_SlowPercent); + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_Thunder_Damage); + + // 防御符 + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_Barrier_ShieldAmount); + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_IronWall_DefenseBonus); + + // 辅助符 + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_Speed_Bonus); + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_Meditate_ManaRegen); + + // 诅咒符 + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_Weaken_AttackReduce); + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_SoulDrain_Amount); + + // 阵法符 + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_Trap_Radius); + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_SwordArray_PerSwordDamage); + UE_DECLARE_GAMEPLAY_TAG_EXTERN(Talisman_HealField_HealPerTick); +} +``` + +### 四、符箓效果示例:「裂空·雷击符」 + +``` +蓝图配置(BP_GE_Talisman_Thunder_Base): + +Modifiers: + ├─ URPGAttributeSet::Damage + │ ├─ ModifierOp: Override + │ └─ Magnitude: SetByCaller (Tag=Talisman_Thunder_Damage) + ├─ URPGAttributeSet::Tough + │ ├─ ModifierOp: Add + │ └─ Magnitude: SetByCaller (Tag=Talisman_Thunder_Damage) × -0.3 + └─ GameplayTag: + └─ Grant: State.HitReaction.Stagger(击退硬直) + +Duration Policy: Instant + +Damage 计算链: + Base Damage = SetByCaller.Talisman_Thunder_Damage (50) + × TierMultiplier (黄纸=1.0 / 银篆=1.5 / 金印=2.2 / 玉敕=3.0) + × 符修修为加成 (境界 × 0.05) + × 当前灵力系数 (Mana/MaxMana × 0.5 + 0.5) + + 黄纸雷击符 = 50 × 1.0 × 1.0 × 1.0 = 50 伤害 + 15 削韧 + 玉敕雷击符 = 50 × 3.0 × 2.0 × 1.0 = 300 伤害 + 90 削韧 +``` + +### 五、涉及文件清单 + +| 文件(新建/修改) | 内容 | +|------|------| +| `Public/Abilities/Talisman/FRTalismanData.h` | **新建**:符箓数据结构、枚举 | +| `Public/Abilities/Talisman/URPGFuXiuAbilityComponent.h/.cpp` | **新建**:符修 ASC 扩展组件 | +| `Public/Abilities/Talisman/GE_Talisman_*.h` | **新建**:5 类 14 个 GameplayEffect 蓝图基类 | +| `Public/Config/SDHGameTagSettings.h` | **修改**:新增 SetByCaller.Talisman_* Tag | +| `Public/Character/Attribute/RPGAttributeSet.h` | **不变**:符箓几何修改现有 Health/Shield/Tough/Mana/MoveSpeed/AttackPower/DefensePower 属性 | +| `Public/Items/RPGItem.h` | **修改**:新增 `URPGTalismanItem` 物品类型 | +| `.trae/documents/01_策划设计/修仙基础概念设定/修仙流派.md` | **修改**:符修独立为独立流派(当前在魔修路径下) | + +--- + +## 附录:关键文件速查 + +| 缩写 | 全称 | 核心文件位置 | +|------|------|------------| +| LWS | LivingWorldSystem | `Plugins/RPGGameCore/Source/LivingWorldSystem/` | +| GA/GAS | Gameplay Ability System | `Plugins/RPGGameCore/Source/RPGGameplayAbility/` | +| ASC | AbilitySystemComponent | `URPGAbilitySystemComponent` | +| GE | GameplayEffect | UGameplayEffect 蓝图子类 | +| CMC | CharacterMovementComponent | `LCMCharacterMovementComponent` | +| ActionPose | 架势(主姿态) | `ELM_ActionPose` 在 `RPGTypes.h:203`,24 个主架势 | +| SM | SkillStateMachine | `USkillSMInstance` (LogicDriver) | diff --git a/07-Other/AI/AI Agent/UnrealEngine/图谱 vs 传统 NPC 对比测试.md b/07-Other/AI/AI Agent/UnrealEngine/Graphify测试结果/图谱 vs 传统 NPC 对比测试.md similarity index 93% rename from 07-Other/AI/AI Agent/UnrealEngine/图谱 vs 传统 NPC 对比测试.md rename to 07-Other/AI/AI Agent/UnrealEngine/Graphify测试结果/图谱 vs 传统 NPC 对比测试.md index 5d706b3..0543624 100644 --- a/07-Other/AI/AI Agent/UnrealEngine/图谱 vs 传统 NPC 对比测试.md +++ b/07-Other/AI/AI Agent/UnrealEngine/Graphify测试结果/图谱 vs 传统 NPC 对比测试.md @@ -61,3 +61,6 @@ tags: | Token 消耗(估算) | | | | 结果完整性 | /10 | /10 | | 用时 | | | +# 结果 +- No Graphify:[[图谱 vs 传统 NPC 对比测试]] +- Graphify:[[AIDM_NPC与修仙系统分析报告_Graphify]] diff --git a/RPGGameplayAbility重构文档.md b/07-Other/AI/AI Agent/UnrealEngine/RPGGameplayAbility重构/RPGGameplayAbility重构文档.md similarity index 100% rename from RPGGameplayAbility重构文档.md rename to 07-Other/AI/AI Agent/UnrealEngine/RPGGameplayAbility重构/RPGGameplayAbility重构文档.md diff --git a/RPGGameplayAbility重构文档_Sonnet.md b/07-Other/AI/AI Agent/UnrealEngine/RPGGameplayAbility重构/RPGGameplayAbility重构文档_Sonnet.md similarity index 100% rename from RPGGameplayAbility重构文档_Sonnet.md rename to 07-Other/AI/AI Agent/UnrealEngine/RPGGameplayAbility重构/RPGGameplayAbility重构文档_Sonnet.md diff --git a/07-Other/AI/AI Agent/UnrealEngine/UI/Figma MCP =》OpenDesign.md b/07-Other/AI/AI Agent/UnrealEngine/UI/Figma MCP =》OpenDesign.md new file mode 100644 index 0000000..aa23b75 --- /dev/null +++ b/07-Other/AI/AI Agent/UnrealEngine/UI/Figma MCP =》OpenDesign.md @@ -0,0 +1,299 @@ +- MCP & Skill + - ClaudeCode: + - https://developers.figma.com/docs/figma-mcp-server/remote-server-installation/#claude-code + - https://claude.com/plugins/figma + - CodeX Skill: + - https://developers.figma.com/docs/figma-mcp-server/remote-server-installation/#claude-code + - https://github.com/openai/skills/blob/main/skills/.curated/figma-implement-design/SKILL.md + + + +# Skill +--- +name: ui-review +description: "使用 Chrome DevTools MCP + Figma MCP 对 Web 页面进行自动化 UI 走查,对比 Figma 设计稿与实际页面的字体、颜色、间距、布局等差异,检测响应式溢出问题,生成含 CSS 选择器和修复代码的 Bug 清单。当用户提到 UI 走查、设计还原度检查、对比设计稿、帮我走查页面、页面和设计稿对不上、CSS 样式不对、像素级还原、检查页面实现、视觉回归、前端还原度、responsive 问题、移动端适配检查、设计稿 diff 时触发。即使用户只说"帮我看看这个页面"或"这个实现和设计稿差多少",只要涉及设计稿与实现的对比,都应该触发本技能。" +user-invokable: true +args: + - name: figma-url + description: Figma 设计稿链接(含 fileKey 和 nodeId) + required: true + - name: page-url + description: 要走查的实际页面 URL + required: true + - name: breakpoints + description: "要测试的响应式断点,默认: 375,768,1440" + required: false +--- + +# UI 走查 Skill — Chrome DevTools MCP + Figma MCP + +通过 AI 连接真实浏览器和 Figma 设计稿,自动化完成 UI 走查工作。产出一份开发可直接使用的 Bug 修复清单。 + +走查的核心价值在于**发现实现与设计的偏差**——这些偏差在开发时往往难以察觉,但会累积成用户可感知的粗糙感。本技能通过结构化流程确保不遗漏。 + +--- + +## 第零步:环境检查 + +走查依赖两个 MCP Server。如果工具列表中缺少对应工具,引导用户配置。 + +### Chrome DevTools MCP + +需要 `take_screenshot`、`take_snapshot`、`evaluate_script`、`navigate_page` 等工具。如果缺失: + +1. 安装:`npm install -g chrome-devtools-mcp@latest`(需 Node.js >= 20.19.0) +2. 在 `.vscode/mcp.json` 中添加: +```json +{ "servers": { "chrome-devtools": { "command": "npx", "args": ["-y", "chrome-devtools-mcp@latest"], "type": "stdio" } } } +``` +3. `Cmd+Shift+P` → `Reload Window`,确认 MCP 启用 + +### Figma MCP + +需要 `get_figma_data`、`download_figma_images` 工具。如果缺失: + +1. 获取 API Key:Figma → 头像 → Settings → Personal access tokens → 生成 +2. 在 `.vscode/mcp.json` 中添加: +```json +{ + "servers": { + "figma": { + "command": "npx", + "args": ["-y", "figma-developer-mcp", "--stdio"], + "env": { + "FIGMA_API_KEY": "<替换为你的 Figma API Key>" + }, + "type": "stdio" + } + } +} +``` +3. `Cmd+Shift+P` → `Reload Window`,确认 MCP 启用 + +两个 MCP 都就绪后,进入走查流程。 + +--- + +## 第一步:需求确认与走查规划 + +### 1.1 确认走查范围 + +向用户确认: +- **走查页面**:单页面还是多步骤流程(如弹窗步骤 1→2→3→完成)? +- **是否需要登录**:需要则请用户提供测试账号 +- **交互前置条件**:如"点击按钮后出现弹窗" +- **关注的断点**:默认 375px / 768px / 1440px,可自定义 +- **输出格式**:HTML 报告(含一键复制、可局域网分享)或 Markdown(适合 Git/飞书/Notion) + +### 1.2 多步骤流程规划 + +如果是多步骤流程,列出所有步骤,每个步骤都在**桌面端和移动端**分别走查: + +``` +例:艺术家入驻流程 +├── 步骤 0: 欢迎弹窗 +├── 步骤 1: 行为准则 +├── 步骤 2: 基本信息 1/3 +└── 步骤 3: 完成页 +``` + +--- + +## 第二步:获取设计稿数据 + +从 Figma URL 提取 `fileKey` 和 `nodeId`,用 `get_figma_data` 获取设计数据。 + +重点提取的属性(这些是设计还原度对比的基准): + +| 类别 | 属性 | +|------|------| +| 字体 | fontFamily, fontSize, fontWeight, lineHeight, letterSpacing | +| 颜色 | fill colors, text colors(记录 HEX 值和 Design Token 名) | +| 间距 | padding, gap, itemSpacing | +| 圆角 | cornerRadius | +| 尺寸 | width, height | +| 布局 | layoutMode, layoutAlign | +| 效果 | effects (shadow), strokes | + +如果 Figma 有多端设计(移动端/桌面端分开),需分别获取对应的 nodeId。记录 Design Token 名称(如 `--color-primary`),报告中会用到。 + +--- + +## 第三步:获取实际页面数据 + +### 3.1 导航与登录 + +用 `navigate_page` 打开目标 URL(timeout: 60000)。 + +SPA 应用常超时但页面已加载——超时后先用 `list_pages` + `take_screenshot` 确认状态,不必盲目重试。 + +登录流程:`take_snapshot` → `fill` 表单 → `click` 登录 → `wait_for` 成功标志 → 导航到目标页。 + +### 3.2 多步骤交互 + +弹窗/模态框需先触发才能看到。流程:`take_snapshot` 找触发按钮 → `click` → 等待弹窗出现 → 截图+提取样式。 + +> ⚠️ SPA 中弹窗可能不响应普通 click。遇到此情况时,阅读 `references/troubleshooting.md` 中的"SPA 弹窗交互"章节获取详细解决方案(包括 Vue/React 组件直接调用、移动端行为差异等)。 + +### 3.3 截图 + +- 视口截图:`take_screenshot` +- 全页截图:`take_screenshot({ fullPage: true })` +- 始终用 `filePath` 保存到 `screenshots/`,命名规则: + ``` + d01-welcome-desktop.png ← 桌面端 + m01-welcome-mobile.png ← 移动端 + ``` + 截图是 Bug 报告的证据,会嵌入最终报告。 + +### 3.4 提取样式 + +用 `evaluate_script` 注入 JavaScript 提取关键元素的 computed styles。需覆盖:标题(h1-h4)、正文(p, span)、按钮(button, a)、容器(section, [class*=card])、表单(input, textarea, select)、图片(img)、弹窗外层容器。 + +> 📄 高效提取脚本见 `references/extract-styles.md`——一次调用即可获取弹窗内所有元素的样式,避免多次 evaluate_script。 + +--- + +## 第四步:逐项对比 — 设计还原度 + +这是走查的**核心工作**。 + +### 4.1 先抓全局,再看局部 + +在逐页对比之前,先扫描所有页面中**反复出现的组件**。如果某个组件在所有页面中有相同偏差,记录为**全局问题(Global Issue)**,只写一次。这样做是因为全局组件的修复只需改一处 CSS,在每页重复报告只会让开发者困惑。 + +常见全局组件:XXL 按钮、标准输入框、文本域、弹窗容器、标签/徽章。 + +识别方法:第一页提取样式 → 对比 Figma → 如有偏差,后续页面验证是否一致 → 一致则为全局问题。 + +### 4.2 对比维度与容差 + +| 检查项 | 容差标准 | 说明 | +|--------|---------|------| +| fontFamily | 精确匹配 | 字体族必须完全一致 | +| fontSize | ≤1px | 亚像素渲染可能有微小差异 | +| fontWeight | 精确匹配 | 400 vs 500 视觉差异明显 | +| lineHeight | ≤2px | 行高差 1-2px 在正文中不易察觉 | +| letterSpacing | ≤0.5px | 字间距非常敏感 | +| color (RGB各通道) | ≤5 | 颜色管理可能引入微小偏差 | +| padding/margin/gap | ≤2px | 盒模型差异在 2px 内可接受 | +| borderRadius | 精确匹配 | 圆角差异视觉上很明显 | +| box-shadow | 逐项对比 x/y/blur/spread/color | 阴影差异需要拆开比较 | + +对比时注意带透明度的颜色(如 `rgba(28,28,30,0.2)`),alpha 值也要比较。 + +**凡是超出容差的,全部记录为 Bug,包含:Figma 值 → 实际值、CSS 选择器、可复制的修复代码。** + +--- + +## 第五步:响应式走查 + +用 `emulate` 模拟不同断点: + +``` +emulate({ viewport: "375x812x2,mobile,touch" }) // 手机 +emulate({ viewport: "768x1024x2,mobile,touch" }) // 平板 +emulate({ viewport: "1440x900x1" }) // 桌面 +``` + +每个断点执行: +1. **全页截图** — 记录布局 +2. **溢出检测** — 水平溢出是移动端最常见的 Bug,用 `evaluate_script` 检查 `scrollWidth > innerWidth` 的元素 +3. **字号梯度** — 标题在不同断点下字号变化应平滑 +4. **布局断点** — 卡片网格列数、导航折叠是否合理 + +### 移动端深度检查(375px) + +移动端不能只看截图,以下问题截图中看不出来: + +| 检查项 | 原因 | 检测方法 | +|--------|------|----------| +| 弹窗 max-height ≤ 80vh | 超出会被系统裁剪,用户无法操作 | 检查 `.modal` computedStyle.maxHeight | +| 弹窗内部滚动 | 内容溢出时弹窗应内滚,而非页面滚 | 检查 `overflow-y: auto/scroll` | +| 遮罩层 z-index | header/footer 可能穿透遮罩 | 对比 z-index | +| 动画溢出 | 庆祝动画常产生水平滚动条 | 检查容器 `overflow: hidden` | +| 触摸区域 ≥ 44×44px | Apple HIG 最低要求 | 提取 offsetWidth/Height | +| Safe Area | iOS 刘海屏遮挡 | 检查 `env(safe-area-inset-*)` | +| 图片缩放 | 避免拉伸变形 | 检查 `object-fit` | + +--- + +## 第六步:生成 Bug 修复清单 + +### 输出原则 + +- **精简、可执行**:开发拿到就能改,不做鼓励、不做设计评审 +- **每个 Bug 附修复代码**:含 CSS 选择器和可复制代码 +- **全局问题只写一次**:页面级 Bug 只注明"受 G1 影响" + +### 优先级 + +| 级别 | 定义 | +|------|------| +| **P0** | 设计还原度差异 + 影响用户体验(字体/颜色/间距不一致;全断点溢出) | +| **P1** | 建议修复(某些断点溢出;缺交互反馈) | +| **P2** | 可优化(布局建议;排版优化) | + +### 报告结构 + +``` +📋 UI 走查报告 +├── 🌐 全局问题(Global Issues) +├── 📄 页面/步骤 N: [名称](P0 → P1 → P2 排序) +├── 📱 移动端专项检查(375px) +└── 📊 溢出检测汇总表(元素 × 断点矩阵) +``` + +### Bug 卡片格式 + +``` +#编号 Bug 标题 [P0/P1/P2] + 问题描述(元素 / CSS 选择器 / 影响断点) + [标签: 还原度 / 响应式 / 体验] + Figma: xxx → 实际: yyy + 📸 screenshots/d01-xxx.png + 修复代码(可直接复制) +``` + +### HTML 报告(默认) + +单文件 HTML,含:页头信息、全局问题区、分步 Bug 卡片(一键复制按钮)、截图嵌入、移动端专项、溢出矩阵。报告本身也应响应式。可通过 `python3 -m http.server 9090 --bind 0.0.0.0` 局域网分享。 + +### Markdown 报告 + +标准 GFM 格式,截图用相对路径引用 `screenshots/`,适合 Git/飞书/Notion。 + +--- + +## 走查范围 + +### ✅ 必须关注 + +1. **设计还原度**:任何与 Figma 的偏差(字体/颜色/间距/圆角/阴影/尺寸) +2. **全局组件一致性**:按钮、输入框、弹窗等全站统一组件 +3. **响应式布局**:各断点溢出、布局断裂、内容裁剪 +4. **移动端交互**:弹窗高度、内部滚动、触摸区域、z-index +5. **图标还原**:设计稿矢量图标 vs 实现用 emoji/位图 +6. **表单元素**:输入框/文本域/下拉框的边框/圆角/颜色 +7. **动画溢出**:过渡效果产生意外滚动条 + +### ❌ 不关注 + +1. 测试环境特有内容(vConsole、测试数据) +2. 设计决策(对比度、文案、配色——那是设计过程的决定) +3. 功能逻辑(业务逻辑是功能测试的工作) +4. 后端数据正确性 +5. 浏览器兼容性(除非用户明确要求) +6. 性能、SEO、可访问性(除非用户明确要求) + +--- + +## 参考文件 + +遇到以下场景时,阅读对应的参考文件: + +| 场景 | 参考文件 | +|------|---------| +| SPA 弹窗不弹出、导航超时、页面太多 | `references/troubleshooting.md` | +| 需要批量提取 CSS 样式的 JS 脚本 | `references/extract-styles.md` | +| 走查过程中对照检查项清单 | `references/checklist.md` | diff --git a/07-Other/AI/AI Agent/UnrealEngine/Windows Terminal Claude Code 快捷方式.md b/07-Other/AI/AI Agent/UnrealEngine/Windows Terminal Claude Code 快捷方式.md new file mode 100644 index 0000000..35c5100 --- /dev/null +++ b/07-Other/AI/AI Agent/UnrealEngine/Windows Terminal Claude Code 快捷方式.md @@ -0,0 +1,99 @@ +--- +tags: + - windows + - claude-code + - tooling +created: 2026-05-31 +--- +# Windows Terminal 快捷方式启动 Claude Code 项目 + +## 原理 + +桌面快捷方式(`.lnk`)先启动 Windows Terminal,再由 Windows Terminal 的 Profile 定义工作目录和启动命令,最终自动进入指定项目的 Claude Code 会话。 + +``` +桌面快捷方式 (.lnk) + → wt.exe -p "ProfileName" + → Windows Terminal 读取 settings.json 中对应 Profile + → cmd.exe /k "cd 项目目录 && claude --dangerously-skip-permissions" + → Claude Code 启动,进入交互会话 +``` + +## 两层结构 + +### 1. Windows Terminal Profile(settings.json) + +位置:`%LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json` + +每个项目一个 Profile,例如: + +```json +{ + "guid": "{30e2bee9-2311-49a4-9798-fe50e1fb872e}", + "name": "AIDM", + "commandline": "cmd.exe /k \"cd /d D:\\MatrixTA\\AIGameDev\\AIDM && set CLAUDE_CODE_DISABLE_TERMINAL_TITLE=1 && claude --dangerously-skip-permissions\"", + "startingDirectory": "D:\\MatrixTA\\AIGameDev\\AIDM", + "tabColor": "#16A34A", + "suppressApplicationTitle": true, + "icon": "🎮", + "hidden": false +} +``` + +字段说明: + +| 字段 | 作用 | +|------|------| +| `guid` | 唯一标识,内部匹配用 | +| `name` | 显示在下拉菜单和标签页标题,也是 `-p` 参数的匹配值 | +| `commandline` | 实际执行的命令,通过 `cmd.exe /k` 保证窗口保持 | +| `startingDirectory` | 初始工作目录 | +| `tabColor` | 标签页颜色,方便区分项目 | +| `suppressApplicationTitle` | 禁止应用修改终端标题 | +| `icon` | 标签页图标(emoji) | + +### 2. 桌面快捷方式(.lnk) + +PowerShell 创建方式: + +```powershell +$shell = New-Object -ComObject WScript.Shell +$desktop = [Environment]::GetFolderPath('Desktop') +$shortcut = $shell.CreateShortcut("$desktop\AIDM.lnk") +$shortcut.TargetPath = "C:\Users\loujiajie\AppData\Local\Microsoft\WindowsApps\wt.exe" +$shortcut.Arguments = '-p "AIDM"' +$shortcut.WorkingDirectory = "D:\MatrixTA\AIGameDev\AIDM" +$shortcut.Save() +``` + +字段说明: + +| 属性 | 值 | 说明 | +|------|-----|------| +| `TargetPath` | `wt.exe` 完整路径 | Windows Terminal 可执行文件 | +| `Arguments` | `-p "ProfileName"` | 匹配 settings.json 中 Profile 的 `name` 字段 | +| `WorkingDirectory` | 项目目录 | 与 Profile 中的 `startingDirectory` 一致 | + +## 新增项目的步骤 + +> [!note] 完整流程 +> 1. 在 `settings.json` 的 `profiles.list` 数组中添加新 Profile +> 2. 生成新的 GUID(PowerShell: `[guid]::NewGuid()`) +> 3. 创建桌面 `.lnk` 快捷方式指向 `wt.exe -p "新Profile名"` + +## 已有项目 Profile 一览 + +| 项目 | Tab 颜色 | 图标 | 目录 | +|------|----------|------|------| +| CharacterMaker | `#1E3CB4` (蓝) | 🔥 | `D:\AI\Website\CharacterMaker` | +| AIDM | `#16A34A` (绿) | 🎮 | `D:\MatrixTA\AIGameDev\AIDM` | +| POPODocs | `#0078D7` (蓝) | 📄 | `D:\AI\Skill\MatrixAITA-POPODocs-Skill` | +| NeteaseAITA_Artlib | `#808080` (灰) | 🎨 | `D:\AI\Website\NeteaseAITA_Artlib` | + +## 关键细节 + +- **`cmd.exe /k`**:执行完后续命令后保持窗口不关闭,用户可继续交互 +- **`--dangerously-skip-permissions`**:跳过 Claude Code 的权限提示,适合本地开发 +- **`CLAUDE_CODE_DISABLE_TERMINAL_TITLE=1`**:禁止 Claude Code 修改终端标题,保持 Profile 名称显示 +- **`suppressApplicationTitle: true`**:配合上一条,双重保障标题不被覆盖 +- **GUID 必须唯一**:每个 Profile 的 `guid` 用于内部匹配,`name` 用于 `-p` 参数匹配