Finish implementing IsKeyUsedByPlayerController
This commit is contained in:
BIN
Content/Luprex/lxGameMode.uasset
LFS
BIN
Content/Luprex/lxGameMode.uasset
LFS
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CommonTypes.generated.h"
|
||||
|
||||
namespace CommonTypes {
|
||||
// Array of tangible IDs.
|
||||
using IdArray = TArray<int64>;
|
||||
@@ -10,3 +12,47 @@ namespace CommonTypes {
|
||||
// Array of std::string_view
|
||||
using StringViewVec = TArray<std::string_view>;
|
||||
}
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxLuaValueType : uint8 {
|
||||
End,
|
||||
String,
|
||||
Name,
|
||||
Float,
|
||||
Boolean,
|
||||
Vector
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// A variety of boolean-like results that can be conveniently
|
||||
// be used in conjunction with 'ExpandEnumAsExecs' to create
|
||||
// branching functions.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxSuccessOrError : uint8 {
|
||||
Success,
|
||||
Error,
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxFoundOrNotFound : uint8 {
|
||||
Found,
|
||||
NotFound,
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxUsedOrNotUsed : uint8 {
|
||||
Used,
|
||||
NotUsed,
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxSuccessOrWrongType : uint8 {
|
||||
Success,
|
||||
WrongType,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ public class Integration : ModuleRules
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"InputCore",
|
||||
"SlateCore",
|
||||
"Sockets",
|
||||
"Networking",
|
||||
"EnhancedInput",
|
||||
|
||||
@@ -15,40 +15,6 @@ class UlxLuaValues;
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxLuaValueType : uint8 {
|
||||
End,
|
||||
String,
|
||||
Name,
|
||||
Float,
|
||||
Boolean,
|
||||
Vector
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// A general-purpose 'success or error' type.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxSuccessOrError : uint8 {
|
||||
Success,
|
||||
Error,
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxFoundOrNotFound : uint8 {
|
||||
Found,
|
||||
NotFound,
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxSuccessOrWrongType : uint8 {
|
||||
Success,
|
||||
WrongType,
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This is a little parser that parses Lua function 'prototypes'.
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
#include "StoreFNameInputModifier.h"
|
||||
#include "EnhancedPlayerInput.h"
|
||||
#include "LuprexGameModeBase.h"
|
||||
|
||||
|
||||
static const int ENCODE_LIMIT = 0x00FFFFFF;
|
||||
|
||||
FInputActionValue UPassFNameAsAxis3D::ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime)
|
||||
{
|
||||
// Internally, an FName is stored as three integers:
|
||||
// ComparisonIndex, DisplayIndex, and Number. These numbers
|
||||
// are only valid within a single unreal process, but that's OK.
|
||||
// We copy these three numbers into an Axis3D.
|
||||
//
|
||||
// Yes, that's ugly. It would be nicer if FName was one
|
||||
// of the types explicitly allowed in an FInputActionValue.
|
||||
// Maybe some day!
|
||||
//
|
||||
// Integers larger than ENCODE_LIMIT cannot be losslessly
|
||||
// converted to float. Such numbers should never occur in
|
||||
// practice: the string table should not contain that many
|
||||
// strings!
|
||||
//
|
||||
uint32 cidx = FNameToStore.GetComparisonIndex().ToUnstableInt();
|
||||
uint32 didx = FNameToStore.GetDisplayIndex().ToUnstableInt();
|
||||
uint32 nidx = FNameToStore.GetNumber();
|
||||
|
||||
// Make sure the three integers will fit into three floats without rounding or overflow.
|
||||
if ((cidx > ENCODE_LIMIT) || (didx > ENCODE_LIMIT) || (nidx > ENCODE_LIMIT))
|
||||
{
|
||||
UE_LOG(LogLuprexIntegration, Error, TEXT("Name cannot be converted to FInputActionValue: %s"), *FNameToStore.ToString());
|
||||
return FInputActionValue(FVector());
|
||||
}
|
||||
|
||||
return FInputActionValue(FVector(cidx, didx, nidx));
|
||||
}
|
||||
|
||||
FName UPassFNameAsAxis3D::DecodeFNameFromAxis3D(const FVector &Vec)
|
||||
{
|
||||
uint32 cidx = static_cast<uint32>(Vec.X);
|
||||
uint32 didx = static_cast<uint32>(Vec.Y);
|
||||
uint32 nidx = static_cast<uint32>(Vec.Z);
|
||||
FName Result(FNameEntryId::FromUnstableInt(cidx), FNameEntryId::FromUnstableInt(didx), nidx);
|
||||
FName Inverse(FNameEntryId::FromUnstableInt(didx), FNameEntryId::FromUnstableInt(cidx), nidx);
|
||||
|
||||
if ((double(cidx) != Vec.X) || (double(didx) != Vec.Y) || (double(nidx) != Vec.Z) ||
|
||||
(cidx > ENCODE_LIMIT) || (didx > ENCODE_LIMIT) || (nidx > ENCODE_LIMIT) ||
|
||||
(!Result.IsValid()) || (!Inverse.IsValid()))
|
||||
{
|
||||
UE_LOG(LogLuprexIntegration, Error, TEXT("FVector is not an encoded FName."));
|
||||
return NAME_None;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "InputModifiers.h"
|
||||
#include "StoreFNameInputModifier.generated.h"
|
||||
|
||||
/**
|
||||
* @brief Allows you to pass an FName into an event handler.
|
||||
*
|
||||
* This modifier allows you to type an FName directly into an input mapping in
|
||||
* the InputMappingContext editor, and have that FName passed through to an
|
||||
* enhanced input handler.
|
||||
*
|
||||
* This modifier has an FName UPROPERTY which is editable in the InputMappingContext
|
||||
* editor. At runtime, it encodes the FName as an Axis3D. In the event handler,
|
||||
* the Axis3D can be decoded back into an FName using DecodeFNameFromAxis3D.
|
||||
*
|
||||
* One use for this modifier is when you want to know exactly which
|
||||
* keyboard key triggered an EnhancedInput event. You can put the key's FName
|
||||
* into the InputMappingContext, and it will get passed through to the event
|
||||
* handler.
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class INTEGRATION_API UPassFNameAsAxis3D : public UInputModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief The FName to be encoded into the FInputActionValue.
|
||||
*
|
||||
* This property can be configured in the Input Mapping Context editor
|
||||
* for each specific mapping.
|
||||
*
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Modifier Settings")
|
||||
FName FNameToStore;
|
||||
|
||||
protected:
|
||||
virtual FInputActionValue ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) override;
|
||||
|
||||
/**
|
||||
* @brief Decodes an FName that was passed by the PassFnameAsAxis3D modifier.
|
||||
*
|
||||
* This function is used in an enhanced input event, where the PassFNameAsAxis3D
|
||||
* modifier was used to pass an FName into the event. The value shows up as
|
||||
* an Axis3D, which much be decoded back into an FName.
|
||||
*
|
||||
*/
|
||||
UFUNCTION(BlueprintPure, Category = "Input|Enhanced")
|
||||
static FName DecodeFNameFromAxis3D(const FVector& Encoded);
|
||||
|
||||
};
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "Components/GridPanel.h"
|
||||
#include "InputMappingContext.h"
|
||||
|
||||
#include "EnhancedInputComponent.h"
|
||||
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Luprex Utility"
|
||||
@@ -212,20 +212,80 @@ void UlxUtilityLibrary::GetPositionOfGridPanelMiddleCell(UGridPanel *GridPanel,
|
||||
}
|
||||
}
|
||||
|
||||
void UlxUtilityLibrary::MapAllKeyboardKeysToOneInputAction(UInputMappingContext *IMC, UInputAction *Action)
|
||||
ElxUsedOrNotUsed UlxUtilityLibrary::IsKeyUsedByMappingContext(const FKeyEvent &KeyEvent, const UInputMappingContext *MappingContext)
|
||||
{
|
||||
TArray<FKey> AllKeys;
|
||||
EKeys::GetAllKeys(AllKeys);
|
||||
FKey Key = KeyEvent.GetKey();
|
||||
|
||||
// Map every keyboard key to the provided LuaAction
|
||||
for (const FKey& Key : AllKeys)
|
||||
if (!MappingContext)
|
||||
{
|
||||
if ((Key.IsValid()) &&
|
||||
(Key.IsBindableInBlueprints()) &&
|
||||
(Key.GetMenuCategory() == EKeys::NAME_KeyboardCategory) &&
|
||||
(!Key.IsModifierKey()))
|
||||
return ElxUsedOrNotUsed::NotUsed;
|
||||
}
|
||||
|
||||
for (const FEnhancedActionKeyMapping& Mapping : MappingContext->GetMappings())
|
||||
{
|
||||
if (Mapping.Key == Key)
|
||||
{
|
||||
IMC->MapKey(Action, Key);
|
||||
return ElxUsedOrNotUsed::Used;
|
||||
}
|
||||
}
|
||||
|
||||
return ElxUsedOrNotUsed::NotUsed;
|
||||
}
|
||||
|
||||
class UEnhancedPlayerInputExposed : public UEnhancedPlayerInput
|
||||
{
|
||||
public:
|
||||
const TArray<FEnhancedActionKeyMapping>& GetEnhancedActionMappings() const { return UEnhancedPlayerInput::GetEnhancedActionMappings(); }
|
||||
};
|
||||
|
||||
ElxUsedOrNotUsed UlxUtilityLibrary::IsKeyUsedByPlayerController(const FKeyEvent &KeyEvent, bool IncludeEscapeAndFkeys, const APlayerController *PlayerController, const UObject *Context)
|
||||
{
|
||||
if (PlayerController == nullptr) PlayerController = Context->GetWorld()->GetFirstPlayerController();
|
||||
|
||||
FKey Key = KeyEvent.GetKey();
|
||||
|
||||
UEnhancedPlayerInput *PlayerInput = Cast<UEnhancedPlayerInput>(PlayerController->PlayerInput);
|
||||
if (PlayerInput == nullptr)
|
||||
{
|
||||
return ElxUsedOrNotUsed::NotUsed;
|
||||
}
|
||||
UEnhancedPlayerInputExposed *Exposed = static_cast<UEnhancedPlayerInputExposed *>(PlayerInput);
|
||||
|
||||
for (const FInputActionKeyMapping& ActionMapping : Exposed->ActionMappings)
|
||||
{
|
||||
if (ActionMapping.Key == Key)
|
||||
{
|
||||
return ElxUsedOrNotUsed::Used; // Found a match in legacy Action Mappings.
|
||||
}
|
||||
}
|
||||
|
||||
for (const FInputAxisKeyMapping& AxisMapping : Exposed->AxisMappings)
|
||||
{
|
||||
if (AxisMapping.Key == Key)
|
||||
{
|
||||
return ElxUsedOrNotUsed::Used; // Found a match in legacy Axis Mappings.
|
||||
}
|
||||
}
|
||||
|
||||
for (const FEnhancedActionKeyMapping& Mapping : Exposed->GetEnhancedActionMappings())
|
||||
{
|
||||
if (Mapping.Key == Key)
|
||||
{
|
||||
return ElxUsedOrNotUsed::Used; // Found a match in the active, flattened mappings.
|
||||
}
|
||||
}
|
||||
|
||||
if (IncludeEscapeAndFkeys)
|
||||
{
|
||||
if (Key == EKeys::Escape ||
|
||||
Key == EKeys::F1 || Key == EKeys::F2 || Key == EKeys::F3 ||
|
||||
Key == EKeys::F4 || Key == EKeys::F5 || Key == EKeys::F6 ||
|
||||
Key == EKeys::F7 || Key == EKeys::F8 || Key == EKeys::F9 ||
|
||||
Key == EKeys::F10 || Key == EKeys::F11 || Key == EKeys::F12)
|
||||
{
|
||||
return ElxUsedOrNotUsed::Used;
|
||||
}
|
||||
}
|
||||
|
||||
return ElxUsedOrNotUsed::NotUsed;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
|
||||
#include "Input/Events.h"
|
||||
#include "CommonTypes.h"
|
||||
#include "UtilityLibrary.generated.h"
|
||||
|
||||
class UEnhancedInputLocalPlayerSubsystem;
|
||||
@@ -132,13 +133,21 @@ public:
|
||||
UFUNCTION(BlueprintPure, Category="Widget")
|
||||
static void GetPositionOfGridPanelMiddleCell(UGridPanel *GridPanel, FVector2D &UpperLeftXY, FVector2D &LowerRightXY);
|
||||
|
||||
// Create a mapping context that maps all keyboard keys to a single input action.
|
||||
// Check if a given key is used by the mapping context.
|
||||
//
|
||||
// This mapping context is usually meant to be used in conjunction with a
|
||||
// hand-crafted mapping context, to act as a catch-all that catches all
|
||||
// keys that aren't mapped in the hand-crafted mapping.
|
||||
//
|
||||
UFUNCTION(BlueprintCallable, Category="Input", meta=(WorldContext="WorldContextObject"))
|
||||
static void MapAllKeyboardKeysToOneInputAction(UInputMappingContext *IMC, UInputAction *Action);
|
||||
UFUNCTION(BlueprintCallable, Category = "Input", meta = (ExpandEnumAsExecs="ReturnValue"))
|
||||
static ElxUsedOrNotUsed IsKeyUsedByMappingContext(const FKeyEvent &KeyEvent, const UInputMappingContext *MappingContext);
|
||||
|
||||
// Check if a given key is used by the player controller.
|
||||
//
|
||||
// If you pass in a null pointer for the player controller, then this
|
||||
// function will use the first player controller by default.
|
||||
//
|
||||
// If 'Include Escape and FKeys' is checked, then the escape key
|
||||
// and the function keys are also considered to be 'used' by the
|
||||
// player controller. It is generally a good idea to treat these
|
||||
// keys as reserved for play-in-editor.
|
||||
//
|
||||
UFUNCTION(BlueprintCallable, Category = "Input", meta = (WorldContext="Context", ExpandEnumAsExecs="ReturnValue", IncludeEscapeAndFkeys="true"))
|
||||
static ElxUsedOrNotUsed IsKeyUsedByPlayerController(const FKeyEvent &KeyEvent, bool IncludeEscapeAndFkeys, const APlayerController *PlayerController, const UObject *Context);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user