RealtimeStyleTransferRuntime/Source/LyraGame/Input/LyraInputModifiers.cpp

197 lines
7.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "LyraInputModifiers.h"
#include "Settings/LyraSettingsShared.h"
#include "Player/LyraLocalPlayer.h"
#include "EnhancedPlayerInput.h"
#include "GameFramework/PlayerController.h"
#include "Input/LyraAimSensitivityData.h"
DEFINE_LOG_CATEGORY_STATIC(LogLyraInputModifiers, Log, All);
//////////////////////////////////////////////////////////////////////
// LyraInputModifiersHelpers
namespace LyraInputModifiersHelpers
{
/** Returns the owning LyraLocalPlayer of an Enhanced Player Input pointer */
static ULyraLocalPlayer* GetLocalPlayer(const UEnhancedPlayerInput* PlayerInput)
{
if (PlayerInput)
{
if (APlayerController* PC = Cast<APlayerController>(PlayerInput->GetOuter()))
{
return Cast<ULyraLocalPlayer>(PC->GetLocalPlayer());
}
}
return nullptr;
}
}
//////////////////////////////////////////////////////////////////////
// ULyraSettingBasedScalar
FInputActionValue ULyraSettingBasedScalar::ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime)
{
if (ensureMsgf(CurrentValue.GetValueType() != EInputActionValueType::Boolean, TEXT("Setting Based Scalar modifier doesn't support boolean values.")))
{
if (ULyraLocalPlayer* LocalPlayer = LyraInputModifiersHelpers::GetLocalPlayer(PlayerInput))
{
const UClass* SettingsClass = ULyraSettingsShared::StaticClass();
ULyraSettingsShared* SharedSettings = LocalPlayer->GetSharedSettings();
const bool bHasCachedProperty = PropertyCache.Num() == 3;
const FProperty* XAxisValue = bHasCachedProperty ? PropertyCache[0] : SettingsClass->FindPropertyByName(XAxisScalarSettingName);
const FProperty* YAxisValue = bHasCachedProperty ? PropertyCache[1] : SettingsClass->FindPropertyByName(YAxisScalarSettingName);
const FProperty* ZAxisValue = bHasCachedProperty ? PropertyCache[2] : SettingsClass->FindPropertyByName(ZAxisScalarSettingName);
if (PropertyCache.IsEmpty())
{
PropertyCache.Emplace(XAxisValue);
PropertyCache.Emplace(YAxisValue);
PropertyCache.Emplace(ZAxisValue);
}
FVector ScalarToUse = FVector(1.0, 1.0, 1.0);
switch (CurrentValue.GetValueType())
{
case EInputActionValueType::Axis3D:
ScalarToUse.Z = ZAxisValue ? *ZAxisValue->ContainerPtrToValuePtr<double>(SharedSettings) : 1.0;
//[[fallthrough]];
case EInputActionValueType::Axis2D:
ScalarToUse.Y = YAxisValue ? *YAxisValue->ContainerPtrToValuePtr<double>(SharedSettings) : 1.0;
//[[fallthrough]];
case EInputActionValueType::Axis1D:
ScalarToUse.X = XAxisValue ? *XAxisValue->ContainerPtrToValuePtr<double>(SharedSettings) : 1.0;
break;
}
ScalarToUse.X = FMath::Clamp(ScalarToUse.X, MinValueClamp.X, MaxValueClamp.X);
ScalarToUse.Y = FMath::Clamp(ScalarToUse.Y, MinValueClamp.Y, MaxValueClamp.Y);
ScalarToUse.Z = FMath::Clamp(ScalarToUse.Z, MinValueClamp.Z, MaxValueClamp.Z);
return CurrentValue.Get<FVector>() * ScalarToUse;
}
}
return CurrentValue;
}
//////////////////////////////////////////////////////////////////////
// ULyraInputModifierDeadZone
FInputActionValue ULyraInputModifierDeadZone::ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime)
{
EInputActionValueType ValueType = CurrentValue.GetValueType();
ULyraLocalPlayer* LocalPlayer = LyraInputModifiersHelpers::GetLocalPlayer(PlayerInput);
if (ValueType == EInputActionValueType::Boolean || !LocalPlayer)
{
return CurrentValue;
}
ULyraSettingsShared* Settings = LocalPlayer->GetSharedSettings();
ensure(Settings);
float LowerThreshold =
(DeadzoneStick == EDeadzoneStick::MoveStick) ?
Settings->GetGamepadMoveStickDeadZone() :
Settings->GetGamepadLookStickDeadZone();
LowerThreshold = FMath::Clamp(LowerThreshold, 0.0f, 1.0f);
auto DeadZoneLambda = [LowerThreshold, this](const float AxisVal)
{
// We need to translate and scale the input to the +/- 1 range after removing the dead zone.
return FMath::Min(1.f, (FMath::Max(0.f, FMath::Abs(AxisVal) - LowerThreshold) / (UpperThreshold - LowerThreshold))) * FMath::Sign(AxisVal);
};
FVector NewValue = CurrentValue.Get<FVector>();
switch (Type)
{
case EDeadZoneType::Axial:
NewValue.X = DeadZoneLambda(NewValue.X);
NewValue.Y = DeadZoneLambda(NewValue.Y);
NewValue.Z = DeadZoneLambda(NewValue.Z);
break;
case EDeadZoneType::Radial:
if (ValueType == EInputActionValueType::Axis3D)
{
NewValue = NewValue.GetSafeNormal() * DeadZoneLambda(NewValue.Size());
}
else if (ValueType == EInputActionValueType::Axis2D)
{
NewValue = NewValue.GetSafeNormal2D() * DeadZoneLambda(NewValue.Size2D());
}
else
{
NewValue.X = DeadZoneLambda(NewValue.X);
}
break;
}
return NewValue;
}
FLinearColor ULyraInputModifierDeadZone::GetVisualizationColor_Implementation(FInputActionValue SampleValue, FInputActionValue FinalValue) const
{
// Taken from UInputModifierDeadZone::GetVisualizationColor_Implementation
if (FinalValue.GetValueType() == EInputActionValueType::Boolean || FinalValue.GetValueType() == EInputActionValueType::Axis1D)
{
return FLinearColor(FinalValue.Get<float>() == 0.f ? 1.f : 0.f, 0.f, 0.f);
}
return FLinearColor((FinalValue.Get<FVector2D>().X == 0.f ? 0.5f : 0.f) + (FinalValue.Get<FVector2D>().Y == 0.f ? 0.5f : 0.f), 0.f, 0.f);
}
//////////////////////////////////////////////////////////////////////
// ULyraInputModifierGamepadSensitivity
FInputActionValue ULyraInputModifierGamepadSensitivity::ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime)
{
// You can't scale a boolean action type
ULyraLocalPlayer* LocalPlayer = LyraInputModifiersHelpers::GetLocalPlayer(PlayerInput);
if (CurrentValue.GetValueType() == EInputActionValueType::Boolean || !LocalPlayer || !SensitivityLevelTable)
{
return CurrentValue;
}
ULyraSettingsShared* Settings = LocalPlayer->GetSharedSettings();
ensure(Settings);
const ELyraGamepadSensitivity Sensitivity = (TargetingType == ELyraTargetingType::Normal) ? Settings->GetGamepadLookSensitivityPreset() : Settings->GetGamepadTargetingSensitivityPreset();
const float Scalar = SensitivityLevelTable->SensitivtyEnumToFloat(Sensitivity);
return CurrentValue.Get<FVector>() * Scalar;
}
//////////////////////////////////////////////////////////////////////
// ULyraInputModifierAimInversion
FInputActionValue ULyraInputModifierAimInversion::ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime)
{
ULyraLocalPlayer* LocalPlayer = LyraInputModifiersHelpers::GetLocalPlayer(PlayerInput);
if (!LocalPlayer)
{
return CurrentValue;
}
ULyraSettingsShared* Settings = LocalPlayer->GetSharedSettings();
ensure(Settings);
FVector NewValue = CurrentValue.Get<FVector>();
if (Settings->GetInvertVerticalAxis())
{
NewValue.Y *= -1.0f;
}
if (Settings->GetInvertHorizontalAxis())
{
NewValue.X *= -1.0f;
}
return NewValue;
}