From 163092858cf8c134833d7b9fecc6f2aacba512cf Mon Sep 17 00:00:00 2001 From: cit110 <840418418@qq.com> Date: Sun, 26 Apr 2026 16:28:55 +0800 Subject: [PATCH] Route player input through SLS movement --- .../PHYSLSMovementBridgeComponent.cpp | 44 +++++++++++++++++++ .../Private/Player/PHYPlayerController.cpp | 27 ++++-------- .../PHYSLSMovementBridgeComponent.h | 19 ++++++++ 3 files changed, 71 insertions(+), 19 deletions(-) diff --git a/Source/PHY/Private/Locomotion/PHYSLSMovementBridgeComponent.cpp b/Source/PHY/Private/Locomotion/PHYSLSMovementBridgeComponent.cpp index b2bd61c..d2947f6 100644 --- a/Source/PHY/Private/Locomotion/PHYSLSMovementBridgeComponent.cpp +++ b/Source/PHY/Private/Locomotion/PHYSLSMovementBridgeComponent.cpp @@ -4,6 +4,7 @@ #include UE_INLINE_GENERATED_CPP_BY_NAME(PHYSLSMovementBridgeComponent) +#include "Characters/PHYCharacterBase.h" #include "Characters/PHYCharacterSettings.h" #include "Components/SLSCharacterMovementComponent.h" #include "GameFramework/Character.h" @@ -61,3 +62,46 @@ bool UPHYSLSMovementBridgeComponent::InitializeSLSMovementBridge(ACharacter* InC bInitialized = true; return true; } + +bool UPHYSLSMovementBridgeComponent::HandleMoveInput(const FVector2D MoveInput) +{ + if (!EnsureSLSMovementBridgeReady()) + { + return false; + } + + const FRotator YawRotation(0.0f, OwnerCharacter->GetControlRotation().Yaw, 0.0f); + const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); + const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); + const FVector WorldIntent = (ForwardDirection * MoveInput.Y) + (RightDirection * MoveInput.X); + + if (APHYCharacterBase* PHYCharacter = Cast(OwnerCharacter)) + { + PHYCharacter->SetMovementIntent(WorldIntent); + } + + SLSCharacterMovementComponent->Input_OnMove(MoveInput); + return true; +} + +bool UPHYSLSMovementBridgeComponent::HandleLookInput(const FVector2D LookInput) +{ + if (!EnsureSLSMovementBridgeReady()) + { + return false; + } + + SLSCharacterMovementComponent->Input_OnLook(LookInput); + return true; +} + +bool UPHYSLSMovementBridgeComponent::EnsureSLSMovementBridgeReady() +{ + if (bInitialized && OwnerCharacter && SLSCharacterMovementComponent) + { + return true; + } + + ACharacter* Character = OwnerCharacter ? OwnerCharacter.Get() : Cast(GetOwner()); + return InitializeSLSMovementBridge(Character, GenericIntegrationComponent, SLSIntegrationComponent); +} diff --git a/Source/PHY/Private/Player/PHYPlayerController.cpp b/Source/PHY/Private/Player/PHYPlayerController.cpp index fe6ddd8..01d5b7a 100644 --- a/Source/PHY/Private/Player/PHYPlayerController.cpp +++ b/Source/PHY/Private/Player/PHYPlayerController.cpp @@ -7,6 +7,7 @@ #include "Characters/PHYPlayerCharacter.h" #include "GIPS_InputSystemComponent.h" #include "InputActionValue.h" +#include "Locomotion/PHYSLSMovementBridgeComponent.h" #include "Player/PHYPlayerCameraManager.h" #include "PHYGameplayTags.h" @@ -148,21 +149,8 @@ bool APHYPlayerController::HandleMoveInput(const FInputActionInstance& ActionDat CachedMovementInput = IsInputReleased(TriggerEvent) ? FVector2D::ZeroVector : ExtractAxis2D(ActionData.GetValue()); - const FRotator CurrentControlRotation = GetControlRotation(); - const FRotator YawRotation(0.0f, CurrentControlRotation.Yaw, 0.0f); - const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); - const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); - - const FVector WorldIntent = (ForwardDirection * CachedMovementInput.Y) + (RightDirection * CachedMovementInput.X); - PHYCharacter->SetMovementIntent(WorldIntent); - - if (!CachedMovementInput.IsNearlyZero()) - { - PHYCharacter->AddMovementInput(ForwardDirection, CachedMovementInput.Y); - PHYCharacter->AddMovementInput(RightDirection, CachedMovementInput.X); - } - - return true; + UPHYSLSMovementBridgeComponent* SLSMovementBridge = PHYCharacter->GetSLSMovementBridgeComponent(); + return SLSMovementBridge ? SLSMovementBridge->HandleMoveInput(CachedMovementInput) : false; } bool APHYPlayerController::ConsumeMoveProcessorGuard(const ETriggerEvent TriggerEvent) @@ -198,11 +186,12 @@ bool APHYPlayerController::HandleLookInput(const FInputActionInstance& ActionDat CachedLookInput = IsInputReleased(TriggerEvent) ? FVector2D::ZeroVector : ExtractAxis2D(ActionData.GetValue()); CachedRotationInput = FRotator(CachedLookInput.Y, CachedLookInput.X, 0.0f); - if (!CachedLookInput.IsNearlyZero()) + APHYPlayerCharacter* PHYCharacter = GetPHYPlayerCharacter(); + if (!PHYCharacter) { - AddYawInput(CachedLookInput.X); - AddPitchInput(CachedLookInput.Y); + return false; } - return true; + UPHYSLSMovementBridgeComponent* SLSMovementBridge = PHYCharacter->GetSLSMovementBridgeComponent(); + return SLSMovementBridge ? SLSMovementBridge->HandleLookInput(CachedLookInput) : false; } diff --git a/Source/PHY/Public/Locomotion/PHYSLSMovementBridgeComponent.h b/Source/PHY/Public/Locomotion/PHYSLSMovementBridgeComponent.h index 318ac42..6ef2293 100644 --- a/Source/PHY/Public/Locomotion/PHYSLSMovementBridgeComponent.h +++ b/Source/PHY/Public/Locomotion/PHYSLSMovementBridgeComponent.h @@ -35,6 +35,22 @@ public: UFUNCTION(BlueprintCallable, Category="PHY|Locomotion|SLS") bool InitializeSLSMovementBridge(ACharacter* InCharacter, UActorComponent* InGenericIntegrationComponent, USLSIntegrationComponent* InSLSIntegrationComponent = nullptr); + /** + * @brief 通过 SLS 原生移动输入接口处理二维移动输入。 + * @param MoveInput X 为右移输入,Y 为前进输入。 + * @return 成功路由到 SLS 运动组件时返回 true。 + */ + UFUNCTION(BlueprintCallable, Category="PHY|Locomotion|SLS|Input") + bool HandleMoveInput(FVector2D MoveInput); + + /** + * @brief 通过 SLS 原生视角输入接口处理二维视角输入。 + * @param LookInput X 为 Yaw 输入,Y 为 Pitch 输入。 + * @return 成功路由到 SLS 运动组件时返回 true。 + */ + UFUNCTION(BlueprintCallable, Category="PHY|Locomotion|SLS|Input") + bool HandleLookInput(FVector2D LookInput); + /** @brief 获取桥接到的角色。 */ UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Locomotion|SLS") ACharacter* GetOwnerCharacter() const { return OwnerCharacter; } @@ -56,6 +72,9 @@ public: bool IsSLSMovementBridgeInitialized() const { return bInitialized; } protected: + /** @brief 确保桥接组件已经缓存角色和 SLS 运动组件。 */ + bool EnsureSLSMovementBridgeReady(); + /** @brief 拥有 SLS 运动能力的角色。 */ UPROPERTY(Transient, BlueprintReadOnly, Category="PHY|Locomotion|SLS") TObjectPtr OwnerCharacter;