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
|
#pragma once
|
||||||
|
|
||||||
|
#include "CommonTypes.generated.h"
|
||||||
|
|
||||||
namespace CommonTypes {
|
namespace CommonTypes {
|
||||||
// Array of tangible IDs.
|
// Array of tangible IDs.
|
||||||
using IdArray = TArray<int64>;
|
using IdArray = TArray<int64>;
|
||||||
@@ -10,3 +12,47 @@ namespace CommonTypes {
|
|||||||
// Array of std::string_view
|
// Array of std::string_view
|
||||||
using StringViewVec = TArray<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",
|
"CoreUObject",
|
||||||
"Engine",
|
"Engine",
|
||||||
"InputCore",
|
"InputCore",
|
||||||
|
"SlateCore",
|
||||||
"Sockets",
|
"Sockets",
|
||||||
"Networking",
|
"Networking",
|
||||||
"EnhancedInput",
|
"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'.
|
// 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 "Blueprint/UserWidget.h"
|
||||||
#include "Components/GridPanel.h"
|
#include "Components/GridPanel.h"
|
||||||
#include "InputMappingContext.h"
|
#include "InputMappingContext.h"
|
||||||
|
#include "EnhancedInputComponent.h"
|
||||||
|
|
||||||
|
|
||||||
#define LOCTEXT_NAMESPACE "Luprex Utility"
|
#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;
|
FKey Key = KeyEvent.GetKey();
|
||||||
EKeys::GetAllKeys(AllKeys);
|
|
||||||
|
if (!MappingContext)
|
||||||
// Map every keyboard key to the provided LuaAction
|
|
||||||
for (const FKey& Key : AllKeys)
|
|
||||||
{
|
{
|
||||||
if ((Key.IsValid()) &&
|
return ElxUsedOrNotUsed::NotUsed;
|
||||||
(Key.IsBindableInBlueprints()) &&
|
}
|
||||||
(Key.GetMenuCategory() == EKeys::NAME_KeyboardCategory) &&
|
|
||||||
(!Key.IsModifierKey()))
|
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 "CoreMinimal.h"
|
||||||
#include "Kismet/KismetSystemLibrary.h"
|
#include "Kismet/KismetSystemLibrary.h"
|
||||||
|
#include "Input/Events.h"
|
||||||
|
#include "CommonTypes.h"
|
||||||
#include "UtilityLibrary.generated.h"
|
#include "UtilityLibrary.generated.h"
|
||||||
|
|
||||||
class UEnhancedInputLocalPlayerSubsystem;
|
class UEnhancedInputLocalPlayerSubsystem;
|
||||||
@@ -132,13 +133,21 @@ public:
|
|||||||
UFUNCTION(BlueprintPure, Category="Widget")
|
UFUNCTION(BlueprintPure, Category="Widget")
|
||||||
static void GetPositionOfGridPanelMiddleCell(UGridPanel *GridPanel, FVector2D &UpperLeftXY, FVector2D &LowerRightXY);
|
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
|
UFUNCTION(BlueprintCallable, Category = "Input", meta = (ExpandEnumAsExecs="ReturnValue"))
|
||||||
// hand-crafted mapping context, to act as a catch-all that catches all
|
static ElxUsedOrNotUsed IsKeyUsedByMappingContext(const FKeyEvent &KeyEvent, const UInputMappingContext *MappingContext);
|
||||||
// keys that aren't mapped in the hand-crafted mapping.
|
|
||||||
//
|
|
||||||
UFUNCTION(BlueprintCallable, Category="Input", meta=(WorldContext="WorldContextObject"))
|
|
||||||
static void MapAllKeyboardKeysToOneInputAction(UInputMappingContext *IMC, UInputAction *Action);
|
|
||||||
|
|
||||||
|
// 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