diff --git a/Source/PHY/Private/Characters/PHYPlayerCharacter.cpp b/Source/PHY/Private/Characters/PHYPlayerCharacter.cpp index e8e1cc2..ed536c2 100644 --- a/Source/PHY/Private/Characters/PHYPlayerCharacter.cpp +++ b/Source/PHY/Private/Characters/PHYPlayerCharacter.cpp @@ -7,11 +7,14 @@ #include "Camera/CameraComponent.h" #include "Camera/PHYUGCSpringArmComponent.h" #include "GameFramework/SpringArmComponent.h" +#include "GIPS_InputSystemComponent.h" #include "Player/PHYPlayerState.h" APHYPlayerCharacter::APHYPlayerCharacter(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { + InputSystemComponent = CreateDefaultSubobject(TEXT("InputSystemComponent")); + CameraBoom = CreateDefaultSubobject(TEXT("CameraBoom")); CameraBoom->SetupAttachment(GetRootComponent()); CameraBoom->TargetArmLength = 320.0f; diff --git a/Source/PHY/Private/Player/PHYPlayerController.cpp b/Source/PHY/Private/Player/PHYPlayerController.cpp index ad22258..d9c5e0d 100644 --- a/Source/PHY/Private/Player/PHYPlayerController.cpp +++ b/Source/PHY/Private/Player/PHYPlayerController.cpp @@ -64,15 +64,32 @@ APHYPlayerCharacter* APHYPlayerController::GetPHYPlayerCharacter() const return Cast(GetPawn()); } -void APHYPlayerController::BindInputEvents() +UGIPS_InputSystemComponent* APHYPlayerController::GetInputSystemComponent() const { - if (!InputSystemComponent) + if (const APHYPlayerCharacter* PHYCharacter = GetPHYPlayerCharacter()) { - return; + if (UGIPS_InputSystemComponent* CharacterInputSystemComponent = PHYCharacter->GetInputSystemComponent()) + { + return CharacterInputSystemComponent; + } } - InputSystemComponent->OnReceivedInput.RemoveDynamic(this, &ThisClass::OnReceivedInput); - InputSystemComponent->OnReceivedInput.AddDynamic(this, &ThisClass::OnReceivedInput); + return InputSystemComponent; +} + +void APHYPlayerController::BindInputEvents() +{ + if (BoundInputSystemComponent) + { + BoundInputSystemComponent->OnReceivedInput.RemoveDynamic(this, &ThisClass::OnReceivedInput); + } + + BoundInputSystemComponent = GetInputSystemComponent(); + if (BoundInputSystemComponent) + { + BoundInputSystemComponent->OnReceivedInput.RemoveDynamic(this, &ThisClass::OnReceivedInput); + BoundInputSystemComponent->OnReceivedInput.AddDynamic(this, &ThisClass::OnReceivedInput); + } } void APHYPlayerController::OnReceivedInput(const FInputActionInstance& ActionData, const FGameplayTag& InputTag, const ETriggerEvent TriggerEvent) diff --git a/Source/PHY/Public/Characters/PHYPlayerCharacter.h b/Source/PHY/Public/Characters/PHYPlayerCharacter.h index 645f210..0339819 100644 --- a/Source/PHY/Public/Characters/PHYPlayerCharacter.h +++ b/Source/PHY/Public/Characters/PHYPlayerCharacter.h @@ -7,12 +7,13 @@ #include "PHYPlayerCharacter.generated.h" class UCameraComponent; +class UGIPS_InputSystemComponent; class UPHYUGCSpringArmComponent; /** * @brief PHY 玩家角色。 * - * 玩家角色从 PlayerState 获取 ASC,并只持有相机组件,不直接持有输入组件。 + * 玩家角色从 PlayerState 获取 ASC,并持有玩家输入组件与 UGC 相机组件。 */ UCLASS(BlueprintType, Blueprintable) class PHY_API APHYPlayerCharacter : public APHYCharacterBase @@ -37,10 +38,18 @@ public: UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Camera") UCameraComponent* GetFollowCamera() const { return FollowCamera; } + /** @brief 获取玩家角色上的 GenericInputSystem 组件。 */ + UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Input") + UGIPS_InputSystemComponent* GetInputSystemComponent() const { return InputSystemComponent; } + protected: /** @brief 根据当前 PlayerState 初始化 ASC。 */ virtual void InitializeAbilitySystemFromPlayerState(); + /** @brief 玩家角色上的 GenericInputSystem 路由组件。 */ + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Input") + TObjectPtr InputSystemComponent; + /** @brief UGC 项目相机臂。 */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Camera") TObjectPtr CameraBoom; diff --git a/Source/PHY/Public/Player/PHYPlayerController.h b/Source/PHY/Public/Player/PHYPlayerController.h index 3c7c653..53df992 100644 --- a/Source/PHY/Public/Player/PHYPlayerController.h +++ b/Source/PHY/Public/Player/PHYPlayerController.h @@ -13,7 +13,7 @@ class UGIPS_InputSystemComponent; /** * @brief PHY 玩家控制器。 * - * 控制器持有 GenericInputSystem 组件,并将 Input GameplayTag 路由到当前玩家角色、ASC、移动和相机输入缓存。 + * 控制器优先绑定当前玩家角色的 GenericInputSystem 组件,并将 Input GameplayTag 路由到角色、ASC、移动和相机输入缓存。 */ UCLASS(BlueprintType, Blueprintable) class PHY_API APHYPlayerController : public APlayerController @@ -30,9 +30,13 @@ public: /** @brief 接管 Pawn 时刷新输入委托。 */ virtual void OnPossess(APawn* InPawn) override; - /** @brief 获取 GenericInputSystem 组件。 */ + /** @brief 获取当前实际绑定的 GenericInputSystem 组件,优先返回玩家角色上的组件。 */ UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Input") - UGIPS_InputSystemComponent* GetInputSystemComponent() const { return InputSystemComponent; } + UGIPS_InputSystemComponent* GetInputSystemComponent() const; + + /** @brief 获取控制器自身保留的 GenericInputSystem 组件。 */ + UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Input") + UGIPS_InputSystemComponent* GetControllerInputSystemComponent() const { return InputSystemComponent; } /** @brief 获取当前 PHY 玩家角色。 */ UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Input") @@ -64,6 +68,10 @@ protected: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Input") TObjectPtr InputSystemComponent; + /** @brief 当前已经绑定输入委托的组件。 */ + UPROPERTY(Transient) + TObjectPtr BoundInputSystemComponent; + /** @brief 本地移动输入缓存。 */ UPROPERTY(Transient) FVector2D CachedMovementInput = FVector2D::ZeroVector;