diff --git a/AGENTS.md b/AGENTS.md index 7186af9..9bebf3d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -27,7 +27,7 @@ - 相机专家向总架构汇报。主责 `AuroraDevs_UGC`、战斗锁定/瞄准/移动相机状态;不得主动引入 `GenericCameraSystem` 或 `SLSCameraModeSystem` 作为玩法层依赖。 - 战斗/GAS 专家向总架构汇报。主责 ASC、Ability、Attribute、GameplayTag、GameplayCue、伤害、复制、预测。 - 输入专家向总架构汇报。主责 `GenericInputSystem`、`EnhancedInput`、输入到 GAS/UGC/运动/UI 的路由。 -- 运动专家向总架构汇报。主责 `SmoothLocomotionSystem`、`SLSCore`、`TraversalSystem`、`SLSIntegration`、`FootStepSystem`;运动状态只通过项目接口通知相机。 +- 运动专家向总架构汇报。主责 `SmoothLocomotionSystem`、`SLSCore`、`TraversalSystem`、`SLSIntegration`、`FootStepSystem`;`USLSIntegrationComponent` 允许由运动专家集中接入,禁止其它系统散落依赖;运动状态只通过项目接口通知相机。 - UI 专家向总架构汇报。主责 `GenericUISystem`、`CommonUI`、UMG、HUD、输入模式切换。 - 背包专家向总架构汇报。主责 `GenericInventorySystem`、物品、装备、拾取、战斗/UI 联动。 - 交互/效果专家向总架构汇报。主责 `GenericGameSystem`、`GenericEffectsSystem`、`SmartObjects`、`TargetingSystem`、Niagara。 @@ -48,6 +48,7 @@ ## 相机规则 - 项目相机主入口统一使用 Ultimate Gameplay Camera,即 `AuroraDevs_UGC`。 - `GenericCameraSystem` 和 `SLSCameraModeSystem` 只允许作为插件内部依赖、示例资产参考或薄适配层依赖;项目玩法层尽可能不用。 +- `USLSIntegrationComponent` 由运动层集中持有和暴露,不等于允许业务层直接依赖 `SLSCameraModeSystem`。 - 相机状态由项目级接口接收输入、运动和战斗状态,不允许业务代码到处直接耦合多个相机系统。 ## C++ 和配置规则 diff --git a/Source/PHY/PHY.Build.cs b/Source/PHY/PHY.Build.cs index 79e783c..c5c7de0 100644 --- a/Source/PHY/PHY.Build.cs +++ b/Source/PHY/PHY.Build.cs @@ -24,7 +24,9 @@ public class PHY : ModuleRules "GenericInputSystem", "GenericGameSystem", "GenericEffectsSystem", + "SLSCore", "SmoothLocomotionSystem", + "SLSIntegration", "AuroraDevs_UGC", "IKRig", "AIModule" diff --git a/Source/PHY/Private/Characters/PHYCharacterBase.cpp b/Source/PHY/Private/Characters/PHYCharacterBase.cpp index 354d2ab..39ba2f4 100644 --- a/Source/PHY/Private/Characters/PHYCharacterBase.cpp +++ b/Source/PHY/Private/Characters/PHYCharacterBase.cpp @@ -22,6 +22,8 @@ #include "PHYGameplayTags.h" #include "Ragdoll/GGS_RagdollComponent.h" #include "Components/SLSCharacterMovementComponent.h" +#include "SLSIntegrationComponent.h" +#include "SLSIntegrationDataAsset.h" #include "Targeting/GCS_TargetingSystemComponent.h" #include "Team/GCS_CombatTeamAgentComponent.h" @@ -39,6 +41,32 @@ APHYCharacterBase::APHYCharacterBase(const FObjectInitializer& ObjectInitializer ContextEffectComponent = CreateDefaultSubobject(TEXT("ContextEffectComponent")); MeshBridgeComponent = CreateDefaultSubobject(TEXT("MeshBridgeComponent")); SLSMovementBridgeComponent = CreateDefaultSubobject(TEXT("SLSMovementBridgeComponent")); + SLSIntegrationComponent = CreateDefaultSubobject(TEXT("SLSIntegrationComponent")); + + USLSIntegrationDataAsset* SLSIntegrationRuntimeDataAsset = CreateDefaultSubobject(TEXT("SLSIntegrationRuntimeDataAsset")); + if (SLSIntegrationComponent && SLSIntegrationRuntimeDataAsset) + { + FSLSBaseCharacterMovementSettingsOp* MovementSettingsOp = SLSIntegrationRuntimeDataAsset->GetFirstSLSDataOpOfType(); + if (!MovementSettingsOp) + { + MovementSettingsOp = SLSIntegrationRuntimeDataAsset->AddAndGetSLSDataOp(); + } + + if (MovementSettingsOp) + { + if (FSLSBaseCharacterMovementSettings* MovementSettings = static_cast(MovementSettingsOp->GetSettings())) + { + MovementSettings->bAddSkeletalBoneSyncComponent = false; + MovementSettings->Config.InitComponentType = ESLSComponentInitType::ManualInit; + MovementSettings->Config.MovementType = ESLSMovementType::Jog; + MovementSettings->Config.RotationMode = ESLSRotationMode::VelocityDirection; + MovementSettings->Config.bEnableSprintInLookingDirectionRotationMode = true; + } + } + + SLSIntegrationRuntimeDataAsset->InitializeData(); + SLSIntegrationComponent->SLSIntegrationDataAsset = SLSIntegrationRuntimeDataAsset; + } if (UClass* GenericIntegrationClass = FindObject(nullptr, TEXT("/Script/GenericGameSystem.GenericIntegrationComponent"))) { @@ -86,7 +114,7 @@ void APHYCharacterBase::BeginPlay() if (SLSMovementBridgeComponent) { - SLSMovementBridgeComponent->InitializeSLSMovementBridge(this, GenericIntegrationComponent); + SLSMovementBridgeComponent->InitializeSLSMovementBridge(this, GenericIntegrationComponent, SLSIntegrationComponent); } UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(this, UGameFrameworkComponentManager::NAME_GameActorReady); diff --git a/Source/PHY/Private/Locomotion/PHYSLSMovementBridgeComponent.cpp b/Source/PHY/Private/Locomotion/PHYSLSMovementBridgeComponent.cpp index 889444b..b2bd61c 100644 --- a/Source/PHY/Private/Locomotion/PHYSLSMovementBridgeComponent.cpp +++ b/Source/PHY/Private/Locomotion/PHYSLSMovementBridgeComponent.cpp @@ -8,6 +8,7 @@ #include "Components/SLSCharacterMovementComponent.h" #include "GameFramework/Character.h" #include "PHYConfigSettings.h" +#include "SLSIntegrationComponent.h" UPHYSLSMovementBridgeComponent::UPHYSLSMovementBridgeComponent() { @@ -15,11 +16,12 @@ UPHYSLSMovementBridgeComponent::UPHYSLSMovementBridgeComponent() SetIsReplicatedByDefault(false); } -bool UPHYSLSMovementBridgeComponent::InitializeSLSMovementBridge(ACharacter* InCharacter, UActorComponent* InGenericIntegrationComponent) +bool UPHYSLSMovementBridgeComponent::InitializeSLSMovementBridge(ACharacter* InCharacter, UActorComponent* InGenericIntegrationComponent, USLSIntegrationComponent* InSLSIntegrationComponent) { bInitialized = false; OwnerCharacter = InCharacter; GenericIntegrationComponent = InGenericIntegrationComponent; + SLSIntegrationComponent = InSLSIntegrationComponent; SLSCharacterMovementComponent = nullptr; const UPHYLocomotionSettings* LocomotionSettings = GetDefault(); @@ -34,9 +36,14 @@ bool UPHYSLSMovementBridgeComponent::InitializeSLSMovementBridge(ACharacter* InC return false; } + if (!SLSIntegrationComponent) + { + SLSIntegrationComponent = OwnerCharacter->FindComponentByClass(); + } + const UPHYCharacterSettings* CharacterSettings = GetDefault(); - // 首期由项目侧显式初始化,避免依赖 SLSIntegrationComponent 的总装逻辑。 + // 项目侧保留显式初始化,SLSIntegrationComponent 只作为运动层集中集成入口。 SLSCharacterMovementComponent->Config.InitComponentType = ESLSComponentInitType::ManualInit; SLSCharacterMovementComponent->Config.MovementType = ESLSMovementType::Jog; SLSCharacterMovementComponent->Config.RotationMode = ESLSRotationMode::VelocityDirection; diff --git a/Source/PHY/Public/Characters/PHYCharacterBase.h b/Source/PHY/Public/Characters/PHYCharacterBase.h index 924f9f7..c8482ef 100644 --- a/Source/PHY/Public/Characters/PHYCharacterBase.h +++ b/Source/PHY/Public/Characters/PHYCharacterBase.h @@ -22,6 +22,7 @@ class UPHYCharacterStateComponent; class UPHYSLSMovementBridgeComponent; class USkeletalMeshComponent; class USLSCharacterMovementComponent; +class USLSIntegrationComponent; /** * @brief PHY 玩家和 AI 共用角色基类。 @@ -134,6 +135,10 @@ public: UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Character|Locomotion") USLSCharacterMovementComponent* GetSLSCharacterMovementComponent() const; + /** @brief 获取 SLS 集成入口组件。 */ + UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Character|Locomotion") + USLSIntegrationComponent* GetSLSIntegrationComponent() const { return SLSIntegrationComponent; } + /** @brief 获取 GenericGameSystem 可选集成入口组件。 */ UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Character|Locomotion") UActorComponent* GetGenericIntegrationComponent() const { return GenericIntegrationComponent; } @@ -266,6 +271,10 @@ protected: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Character|Locomotion") TObjectPtr SLSMovementBridgeComponent; + /** @brief SLS 插件集成入口组件,由运动层集中接入。 */ + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Character|Locomotion") + TObjectPtr SLSIntegrationComponent; + /** @brief GenericGameSystem 可选集成入口组件。 */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Character|Locomotion") TObjectPtr GenericIntegrationComponent; diff --git a/Source/PHY/Public/Locomotion/PHYSLSMovementBridgeComponent.h b/Source/PHY/Public/Locomotion/PHYSLSMovementBridgeComponent.h index 4b16f2c..318ac42 100644 --- a/Source/PHY/Public/Locomotion/PHYSLSMovementBridgeComponent.h +++ b/Source/PHY/Public/Locomotion/PHYSLSMovementBridgeComponent.h @@ -8,12 +8,13 @@ class ACharacter; class USLSCharacterMovementComponent; +class USLSIntegrationComponent; /** * @brief PHY 对 Smooth Locomotion System 的首期运动桥接组件。 * - * 该组件只缓存并初始化明确接入的 SLS 运动组件,不使用 SLSIntegrationComponent, - * 也不承担相机系统职责。 + * 该组件缓存并初始化明确接入的 SLS 运动组件和 SLSIntegrationComponent, + * 但不承担相机系统职责。 */ UCLASS(BlueprintType, Blueprintable) class PHY_API UPHYSLSMovementBridgeComponent : public UActorComponent @@ -28,10 +29,11 @@ public: * @brief 初始化 SLS 运动桥接。 * @param InCharacter 拥有该桥接组件的角色。 * @param InGenericIntegrationComponent 可选的 Generic 集成入口组件。 + * @param InSLSIntegrationComponent SLS 插件集成入口组件。 * @return 初始化是否成功。 */ UFUNCTION(BlueprintCallable, Category="PHY|Locomotion|SLS") - bool InitializeSLSMovementBridge(ACharacter* InCharacter, UActorComponent* InGenericIntegrationComponent); + bool InitializeSLSMovementBridge(ACharacter* InCharacter, UActorComponent* InGenericIntegrationComponent, USLSIntegrationComponent* InSLSIntegrationComponent = nullptr); /** @brief 获取桥接到的角色。 */ UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Locomotion|SLS") @@ -41,6 +43,10 @@ public: UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Locomotion|SLS") USLSCharacterMovementComponent* GetSLSCharacterMovementComponent() const { return SLSCharacterMovementComponent; } + /** @brief 获取 SLS 插件集成入口组件。 */ + UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Locomotion|SLS") + USLSIntegrationComponent* GetSLSIntegrationComponent() const { return SLSIntegrationComponent; } + /** @brief 获取可选的 Generic 集成入口组件。 */ UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Locomotion|SLS") UActorComponent* GetGenericIntegrationComponent() const { return GenericIntegrationComponent; } @@ -58,6 +64,10 @@ protected: UPROPERTY(Transient, BlueprintReadOnly, Category="PHY|Locomotion|SLS") TObjectPtr SLSCharacterMovementComponent; + /** @brief SLS 插件集成入口组件。 */ + UPROPERTY(Transient, BlueprintReadOnly, Category="PHY|Locomotion|SLS") + TObjectPtr SLSIntegrationComponent; + /** @brief GenericGameSystem 提供的可选集成入口。 */ UPROPERTY(Transient, BlueprintReadOnly, Category="PHY|Locomotion|SLS") TObjectPtr GenericIntegrationComponent;