Add look input processor
This commit is contained in:
@@ -3,3 +3,4 @@ DefaultMappingPriority=0
|
||||
bRouteInputThroughGenericInputSystem=True
|
||||
bBlockGameplayInputWhenUIFocused=True
|
||||
DefaultMoveInputProcessorClass="/Script/PHY.PHYInputProcessor_Move"
|
||||
DefaultLookInputProcessorClass="/Script/PHY.PHYInputProcessor_Look"
|
||||
|
||||
83
Source/PHY/Private/Input/PHYInputProcessor_Look.cpp
Normal file
83
Source/PHY/Private/Input/PHYInputProcessor_Look.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "Input/PHYInputProcessor_Look.h"
|
||||
|
||||
#include UE_INLINE_GENERATED_CPP_BY_NAME(PHYInputProcessor_Look)
|
||||
|
||||
#include "Characters/PHYPlayerCharacter.h"
|
||||
#include "GIPS_InputSystemComponent.h"
|
||||
#include "PHYGameplayTags.h"
|
||||
#include "Player/PHYPlayerController.h"
|
||||
|
||||
UPHYInputProcessor_Look::UPHYInputProcessor_Look()
|
||||
{
|
||||
InputTags.AddTag(PHYGameplayTags::Input_Look);
|
||||
TriggerEvents = {
|
||||
ETriggerEvent::Started,
|
||||
ETriggerEvent::Triggered,
|
||||
ETriggerEvent::Ongoing,
|
||||
ETriggerEvent::Completed,
|
||||
ETriggerEvent::Canceled
|
||||
};
|
||||
}
|
||||
|
||||
bool UPHYInputProcessor_Look::CheckCanHandleInput_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, const FGameplayTag InputTag, const ETriggerEvent TriggerEvent) const
|
||||
{
|
||||
(void)ActionData;
|
||||
(void)TriggerEvent;
|
||||
|
||||
if (!IC || InputTag != PHYGameplayTags::Input_Look)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const APHYPlayerCharacter* PlayerCharacter = Cast<APHYPlayerCharacter>(IC->GetControlledPawn());
|
||||
return PlayerCharacter && PlayerCharacter->GetController<APHYPlayerController>();
|
||||
}
|
||||
|
||||
void UPHYInputProcessor_Look::HandleInputTriggered_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, const FGameplayTag InputTag) const
|
||||
{
|
||||
(void)InputTag;
|
||||
RouteLookInput(IC, ActionData, ETriggerEvent::Triggered);
|
||||
}
|
||||
|
||||
void UPHYInputProcessor_Look::HandleInputStarted_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, const FGameplayTag InputTag) const
|
||||
{
|
||||
(void)InputTag;
|
||||
RouteLookInput(IC, ActionData, ETriggerEvent::Started);
|
||||
}
|
||||
|
||||
void UPHYInputProcessor_Look::HandleInputOngoing_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, const FGameplayTag InputTag) const
|
||||
{
|
||||
(void)InputTag;
|
||||
RouteLookInput(IC, ActionData, ETriggerEvent::Ongoing);
|
||||
}
|
||||
|
||||
void UPHYInputProcessor_Look::HandleInputCanceled_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, const FGameplayTag InputTag) const
|
||||
{
|
||||
(void)InputTag;
|
||||
RouteLookInput(IC, ActionData, ETriggerEvent::Canceled);
|
||||
}
|
||||
|
||||
void UPHYInputProcessor_Look::HandleInputCompleted_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, const FGameplayTag InputTag) const
|
||||
{
|
||||
(void)InputTag;
|
||||
RouteLookInput(IC, ActionData, ETriggerEvent::Completed);
|
||||
}
|
||||
|
||||
FString UPHYInputProcessor_Look::GetEditorFriendlyName_Implementation() const
|
||||
{
|
||||
return TEXT("PHY Look");
|
||||
}
|
||||
|
||||
bool UPHYInputProcessor_Look::RouteLookInput(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, const ETriggerEvent TriggerEvent) const
|
||||
{
|
||||
if (!IC)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
APHYPlayerCharacter* PlayerCharacter = Cast<APHYPlayerCharacter>(IC->GetControlledPawn());
|
||||
APHYPlayerController* PlayerController = PlayerCharacter ? PlayerCharacter->GetController<APHYPlayerController>() : nullptr;
|
||||
return PlayerController ? PlayerController->RouteLookInputFromProcessor(ActionData, TriggerEvent) : false;
|
||||
}
|
||||
@@ -105,7 +105,10 @@ void APHYPlayerController::OnReceivedInput(const FInputActionInstance& ActionDat
|
||||
|
||||
if (InputTag == PHYGameplayTags::Input_Look)
|
||||
{
|
||||
HandleLookInput(ActionData, TriggerEvent);
|
||||
if (!ConsumeLookProcessorGuard(TriggerEvent))
|
||||
{
|
||||
RouteLookInput(ActionData, TriggerEvent);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -127,6 +130,18 @@ bool APHYPlayerController::RouteMoveInputFromProcessor(const FInputActionInstanc
|
||||
return RouteMoveInput(ActionData, TriggerEvent);
|
||||
}
|
||||
|
||||
bool APHYPlayerController::RouteLookInput(const FInputActionInstance& ActionData, const ETriggerEvent TriggerEvent)
|
||||
{
|
||||
return HandleLookInput(ActionData, TriggerEvent);
|
||||
}
|
||||
|
||||
bool APHYPlayerController::RouteLookInputFromProcessor(const FInputActionInstance& ActionData, const ETriggerEvent TriggerEvent)
|
||||
{
|
||||
bLookInputHandledByProcessor = true;
|
||||
LastLookInputProcessorTriggerEvent = TriggerEvent;
|
||||
return RouteLookInput(ActionData, TriggerEvent);
|
||||
}
|
||||
|
||||
bool APHYPlayerController::HandleMoveInput(const FInputActionInstance& ActionData, const ETriggerEvent TriggerEvent)
|
||||
{
|
||||
APHYPlayerCharacter* PHYCharacter = GetPHYPlayerCharacter();
|
||||
@@ -169,6 +184,20 @@ bool APHYPlayerController::ConsumeMoveProcessorGuard(const ETriggerEvent Trigger
|
||||
return false;
|
||||
}
|
||||
|
||||
bool APHYPlayerController::ConsumeLookProcessorGuard(const ETriggerEvent TriggerEvent)
|
||||
{
|
||||
if (bLookInputHandledByProcessor && LastLookInputProcessorTriggerEvent == TriggerEvent)
|
||||
{
|
||||
bLookInputHandledByProcessor = false;
|
||||
LastLookInputProcessorTriggerEvent = ETriggerEvent::None;
|
||||
return true;
|
||||
}
|
||||
|
||||
bLookInputHandledByProcessor = false;
|
||||
LastLookInputProcessorTriggerEvent = ETriggerEvent::None;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool APHYPlayerController::HandleLookInput(const FInputActionInstance& ActionData, const ETriggerEvent TriggerEvent)
|
||||
{
|
||||
CachedLookInput = IsInputReleased(TriggerEvent) ? FVector2D::ZeroVector : ExtractAxis2D(ActionData.GetValue());
|
||||
|
||||
48
Source/PHY/Public/Input/PHYInputProcessor_Look.h
Normal file
48
Source/PHY/Public/Input/PHYInputProcessor_Look.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GIPS_InputProcessor.h"
|
||||
#include "PHYInputProcessor_Look.generated.h"
|
||||
|
||||
/**
|
||||
* @brief PHY 视角输入处理器。
|
||||
*
|
||||
* 该处理器处理 `Input.Look`,并把二维视角输入值路由到当前玩家控制器。
|
||||
*/
|
||||
UCLASS(BlueprintType, Blueprintable, EditInlineNew, DefaultToInstanced)
|
||||
class PHY_API UPHYInputProcessor_Look : public UGIPS_InputProcessor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** @brief 构造默认响应的输入 Tag 和触发事件。 */
|
||||
UPHYInputProcessor_Look();
|
||||
|
||||
protected:
|
||||
/** @brief 检查当前输入组件是否能处理视角输入。 */
|
||||
virtual bool CheckCanHandleInput_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, FGameplayTag InputTag, ETriggerEvent TriggerEvent) const override;
|
||||
|
||||
/** @brief 处理 Triggered 视角输入。 */
|
||||
virtual void HandleInputTriggered_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, FGameplayTag InputTag) const override;
|
||||
|
||||
/** @brief 处理 Started 视角输入。 */
|
||||
virtual void HandleInputStarted_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, FGameplayTag InputTag) const override;
|
||||
|
||||
/** @brief 处理 Ongoing 视角输入。 */
|
||||
virtual void HandleInputOngoing_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, FGameplayTag InputTag) const override;
|
||||
|
||||
/** @brief 处理 Canceled 视角输入。 */
|
||||
virtual void HandleInputCanceled_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, FGameplayTag InputTag) const override;
|
||||
|
||||
/** @brief 处理 Completed 视角输入。 */
|
||||
virtual void HandleInputCompleted_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, FGameplayTag InputTag) const override;
|
||||
|
||||
/** @brief 返回编辑器里显示的处理器名称。 */
|
||||
virtual FString GetEditorFriendlyName_Implementation() const override;
|
||||
|
||||
private:
|
||||
/** @brief 将视角输入发送给玩家控制器。 */
|
||||
bool RouteLookInput(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, ETriggerEvent TriggerEvent) const;
|
||||
};
|
||||
@@ -59,6 +59,10 @@ public:
|
||||
/** @brief 默认移动输入处理器类,用于创建 GenericInputSystem 控制配置。 */
|
||||
UPROPERTY(Config)
|
||||
TSoftClassPtr<UGIPS_InputProcessor> DefaultMoveInputProcessorClass;
|
||||
|
||||
/** @brief 默认视角输入处理器类,用于创建 GenericInputSystem 控制配置。 */
|
||||
UPROPERTY(Config)
|
||||
TSoftClassPtr<UGIPS_InputProcessor> DefaultLookInputProcessorClass;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -56,6 +56,12 @@ public:
|
||||
/** @brief 从 GenericInputSystem 处理器路由移动输入,并阻止同一事件被广播 fallback 重复执行。 */
|
||||
bool RouteMoveInputFromProcessor(const FInputActionInstance& ActionData, ETriggerEvent TriggerEvent);
|
||||
|
||||
/** @brief 从输入处理器或控制器 fallback 路由视角输入。 */
|
||||
bool RouteLookInput(const FInputActionInstance& ActionData, ETriggerEvent TriggerEvent);
|
||||
|
||||
/** @brief 从 GenericInputSystem 处理器路由视角输入,并阻止同一事件被广播 fallback 重复执行。 */
|
||||
bool RouteLookInputFromProcessor(const FInputActionInstance& ActionData, ETriggerEvent TriggerEvent);
|
||||
|
||||
protected:
|
||||
/** @brief 绑定 GenericInputSystem 输入委托。 */
|
||||
virtual void BindInputEvents();
|
||||
@@ -73,6 +79,9 @@ protected:
|
||||
/** @brief 查询并消费移动处理器留下的重复执行保护。 */
|
||||
virtual bool ConsumeMoveProcessorGuard(ETriggerEvent TriggerEvent);
|
||||
|
||||
/** @brief 查询并消费视角处理器留下的重复执行保护。 */
|
||||
virtual bool ConsumeLookProcessorGuard(ETriggerEvent TriggerEvent);
|
||||
|
||||
/** @brief GenericInputSystem 路由组件。 */
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Input")
|
||||
TObjectPtr<UGIPS_InputSystemComponent> InputSystemComponent;
|
||||
@@ -100,4 +109,12 @@ protected:
|
||||
/** @brief 最近一次由输入处理器处理的 Move 触发事件。 */
|
||||
UPROPERTY(Transient)
|
||||
ETriggerEvent LastMoveInputProcessorTriggerEvent = ETriggerEvent::None;
|
||||
|
||||
/** @brief 输入处理器是否已经处理了最近一次 Look 输入。 */
|
||||
UPROPERTY(Transient)
|
||||
bool bLookInputHandledByProcessor = false;
|
||||
|
||||
/** @brief 最近一次由输入处理器处理的 Look 触发事件。 */
|
||||
UPROPERTY(Transient)
|
||||
ETriggerEvent LastLookInputProcessorTriggerEvent = ETriggerEvent::None;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user