mirror of
https://github.com/Ed94/Cog.git
synced 2026-07-25 08:57:53 +00:00
First Submit
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class CogInput : ModuleRules
|
||||
{
|
||||
public CogInput(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
"CogImgui",
|
||||
"CogDebug",
|
||||
"CogWindow",
|
||||
"EnhancedInput",
|
||||
"InputCore",
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "CogInjectActionInfo.h"
|
||||
|
||||
#include "EnhancedInputSubsystems.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogInjectActionInfo::Inject(UEnhancedInputLocalPlayerSubsystem& EnhancedInput, bool IsTimeToRepeat)
|
||||
{
|
||||
if (Action == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Action->ValueType)
|
||||
{
|
||||
case EInputActionValueType::Boolean:
|
||||
{
|
||||
if (bRepeat)
|
||||
{
|
||||
EnhancedInput.InjectInputForAction(Action, FInputActionValue(IsTimeToRepeat), {}, {});
|
||||
}
|
||||
else
|
||||
{
|
||||
EnhancedInput.InjectInputForAction(Action, FInputActionValue(bPressed), {}, {});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case EInputActionValueType::Axis1D:
|
||||
{
|
||||
EnhancedInput.InjectInputForAction(Action, FInputActionValue(X), {}, {});
|
||||
break;
|
||||
}
|
||||
|
||||
case EInputActionValueType::Axis2D:
|
||||
{
|
||||
EnhancedInput.InjectInputForAction(Action, FInputActionValue(FVector2D(X, Y)), {}, {});
|
||||
break;
|
||||
}
|
||||
|
||||
case EInputActionValueType::Axis3D:
|
||||
{
|
||||
EnhancedInput.InjectInputForAction(Action, FInputActionValue(FVector(X, Y, Z)), {}, {});
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "CogInputModule.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FCogInputModule"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogInputModule::StartupModule()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogInputModule::ShutdownModule()
|
||||
{
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FCogInputModule, CogInput)
|
||||
@@ -0,0 +1,204 @@
|
||||
#include "CogInputWindow_Actions.h"
|
||||
|
||||
#include "CogInputDataAsset_Actions.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
#include "Engine/LocalPlayer.h"
|
||||
#include "EnhancedInputSubsystems.h"
|
||||
#include "GameFramework/Pawn.h"
|
||||
#include "InputAction.h"
|
||||
#include "InputMappingContext.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogInputWindow_Actions::UCogInputWindow_Actions()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogInputWindow_Actions::PreRender(ImGuiWindowFlags& WindowFlags)
|
||||
{
|
||||
WindowFlags = ImGuiWindowFlags_MenuBar;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void DrawAxis(const char* Format, const char* ActionName, float CurrentValue, float* InjectValue)
|
||||
{
|
||||
ImGui::PushID(Format);
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(Format, ActionName);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::SliderFloat("##Value", &CurrentValue, -1.0f, 1.0f, "%0.2f");
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
FCogWindowWidgets::SliderWithReset("##Inject", InjectValue, -1.0f, 1.0f, 0.0f, "%0.2f");
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogInputWindow_Actions::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
if (ActionsAsset == nullptr || ActionsAsset->MappingContext == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
||||
if (LocalPlayer == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UEnhancedInputLocalPlayerSubsystem* EnhancedInputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(LocalPlayer);
|
||||
if (EnhancedInputSubsystem == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
{
|
||||
ImGui::SliderFloat("##Repeat", &RepeatPeriod, 0.1f, 10.0f, "Repeat: %0.1fs");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Reset"))
|
||||
{
|
||||
for (FCogInjectActionInfo& ActionInfo : Actions)
|
||||
{
|
||||
ActionInfo.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
if (Actions.Num() == 0)
|
||||
{
|
||||
for (const FEnhancedActionKeyMapping& Mapping : ActionsAsset->MappingContext->GetMappings())
|
||||
{
|
||||
if (Mapping.Action != nullptr && Actions.ContainsByPredicate([&Mapping](const FCogInjectActionInfo& ActionInfo) { return Mapping.Action == ActionInfo.Action; }) == false)
|
||||
{
|
||||
FCogInjectActionInfo& ActionInfo = Actions.AddDefaulted_GetRef();
|
||||
ActionInfo.Action = Mapping.Action;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("Actions", 3, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize))
|
||||
{
|
||||
ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("Inject", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
int Index = 0;
|
||||
|
||||
for (FCogInjectActionInfo& ActionInfo : Actions)
|
||||
{
|
||||
ImGui::PushID(Index);
|
||||
|
||||
const char* ActionName = TCHAR_TO_ANSI(*ActionInfo.Action->GetName());
|
||||
|
||||
FInputActionValue ActionValue = EnhancedInputSubsystem->GetPlayerInput()->GetActionValue(ActionInfo.Action);
|
||||
|
||||
switch (ActionInfo.Action->ValueType)
|
||||
{
|
||||
case EInputActionValueType::Boolean:
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", ActionName);
|
||||
|
||||
const ImVec4 ActiveColor(1, 0.8f, 0, 1);
|
||||
const ImVec4 InnactiveColor(0.3f, 0.3f, 0.3f, 1);
|
||||
const ImVec2 ButtonWidth(FCogWindowWidgets::TextBaseWidth * 10, 0);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::BeginDisabled();
|
||||
bool Value = ActionValue.Get<bool>();
|
||||
FCogWindowWidgets::ToggleButton(&Value, "Pressed##Value", "Released##Value", ActiveColor, InnactiveColor, ButtonWidth);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
FCogWindowWidgets::ToggleButton(&ActionInfo.bPressed, "Pressed##Inject", "Released##Inject", ActiveColor, InnactiveColor, ButtonWidth);
|
||||
ImGui::SameLine();
|
||||
FCogWindowWidgets::ToggleButton(&ActionInfo.bRepeat, "Repeat", "Repeat", ActiveColor, InnactiveColor, ButtonWidth);
|
||||
break;
|
||||
}
|
||||
|
||||
case EInputActionValueType::Axis1D:
|
||||
{
|
||||
const float Value = ActionValue.Get<float>();
|
||||
DrawAxis("%s", ActionName, Value, &ActionInfo.X);
|
||||
break;
|
||||
}
|
||||
|
||||
case EInputActionValueType::Axis2D:
|
||||
{
|
||||
const FVector2D Value = ActionValue.Get<FVector2D>();
|
||||
DrawAxis("%s X", ActionName, Value.X, &ActionInfo.X);
|
||||
DrawAxis("%s Y", ActionName, Value.Y, &ActionInfo.Y);
|
||||
break;
|
||||
}
|
||||
|
||||
case EInputActionValueType::Axis3D:
|
||||
{
|
||||
const FVector Value = ActionValue.Get<FVector>();
|
||||
DrawAxis("%s X", ActionName, Value.X, &ActionInfo.X);
|
||||
DrawAxis("%s Y", ActionName, Value.Y, &ActionInfo.Y);
|
||||
DrawAxis("%s Z", ActionName, Value.Z, &ActionInfo.Z);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
Index++;
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogInputWindow_Actions::RenderTick(float DeltaSeconds)
|
||||
{
|
||||
Super::RenderTick(DeltaSeconds);
|
||||
|
||||
if (GetWorld() == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
||||
if (LocalPlayer == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UEnhancedInputLocalPlayerSubsystem* EnhancedInput = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(LocalPlayer);
|
||||
if (EnhancedInput == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool IsTimeToRepeat = false;
|
||||
float WorldTime = GetWorld()->GetTimeSeconds();
|
||||
if (RepeatTime < WorldTime)
|
||||
{
|
||||
RepeatTime = WorldTime + RepeatPeriod;
|
||||
IsTimeToRepeat = true;
|
||||
}
|
||||
|
||||
for (FCogInjectActionInfo& ActionInfo : Actions)
|
||||
{
|
||||
ActionInfo.Inject(*EnhancedInput, IsTimeToRepeat);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,388 @@
|
||||
#include "CogInputWindow_Gamepad.h"
|
||||
|
||||
#include "CogImguiHelper.h"
|
||||
#include "Engine/LocalPlayer.h"
|
||||
#include "EnhancedInputSubsystems.h"
|
||||
#include "imgui_internal.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogInputWindow_Gamepad::UCogInputWindow_Gamepad()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogInputWindow_Gamepad::PreRender(ImGuiWindowFlags& WindowFlags)
|
||||
{
|
||||
if (bShowAsOverlay)
|
||||
{
|
||||
WindowFlags = ImGuiWindowFlags_NoTitleBar
|
||||
| ImGuiWindowFlags_NoScrollbar
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ImGuiWindowFlags_NoBackground
|
||||
| ImGuiWindowFlags_NoResize;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogInputWindow_Gamepad::InputContextMenu(const FKey& Key, FCogInjectActionInfo* ActionInfoButton, FCogInjectActionInfo* ActionInfo2D)
|
||||
{
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*Key.GetFName().ToString()));
|
||||
ImGui::Separator();
|
||||
|
||||
if (ActionInfoButton != nullptr)
|
||||
{
|
||||
ImGui::Checkbox("Pressed", &ActionInfoButton->bPressed);
|
||||
ImGui::Checkbox("Repeat", &ActionInfoButton->bRepeat);
|
||||
FCogWindowWidgets::SliderWithReset("Period", &RepeatPeriod, 0.0f, 10.0f, 0.5f, "%0.1fs");
|
||||
}
|
||||
|
||||
if (ActionInfoButton != nullptr && ActionInfoButton->Action != nullptr && ActionInfoButton->Action->ValueType == EInputActionValueType::Axis1D)
|
||||
{
|
||||
FCogWindowWidgets::SliderWithReset("X", &ActionInfo2D->X, -1.0f, 1.0f, 0.0f, "%0.2f");
|
||||
}
|
||||
|
||||
if (ActionInfo2D != nullptr)
|
||||
{
|
||||
FCogWindowWidgets::SliderWithReset("X", &ActionInfo2D->X, -1.0f, 1.0f, 0.0f, "%0.2f");
|
||||
FCogWindowWidgets::SliderWithReset("Y", &ActionInfo2D->Y, -1.0f, 1.0f, 0.0f, "%0.2f");
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogInputWindow_Gamepad::OnButtonClicked(FCogInjectActionInfo* ActionInfo)
|
||||
{
|
||||
if (ActionInfo == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ActionInfo->bRepeat)
|
||||
{
|
||||
ActionInfo->bRepeat = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ActionInfo->bPressed = !ActionInfo->bPressed;
|
||||
}
|
||||
|
||||
if (ActionInfo->Action != nullptr)
|
||||
{
|
||||
Input->InjectInputForAction(ActionInfo->Action, FInputActionValue(ActionInfo->bPressed), {}, {});
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogInputWindow_Gamepad::AddButton(const FKey& Key, const ImVec2& RelativePosition, const ImVec2& RelativeSize, const ImVec2& Alignment, float RelativeRounding, ImDrawFlags Flags)
|
||||
{
|
||||
ImGui::PushID((void*)(&Key));
|
||||
|
||||
const float Value = Input->GetKeyValue(Key);
|
||||
|
||||
const ImVec2& Size = RelativeSize * CanvasSize.x;
|
||||
const ImVec2 Position = (CanvasMin + CanvasSize * RelativePosition) - Alignment * Size;
|
||||
|
||||
ImU32 Color = ImGui::GetColorU32(ImLerp(FCogImguiHelper::ToImVec4(ButtonColor), FCogImguiHelper::ToImVec4(PressedColor), Value));
|
||||
|
||||
FCogInjectActionInfo* ActionInfo = Actions.Find(Key);
|
||||
if (ActionInfo != nullptr)
|
||||
{
|
||||
if (ActionInfo->Action != nullptr)
|
||||
{
|
||||
if (Input->GetActionValue(ActionInfo->Action).Get<bool>())
|
||||
{
|
||||
Color = FCogImguiHelper::ToImU32(PressedColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SetCursorScreenPos(Position);
|
||||
if (ImGui::InvisibleButton("", Size))
|
||||
{
|
||||
OnButtonClicked(ActionInfo);
|
||||
}
|
||||
|
||||
InputContextMenu(Key, ActionInfo, nullptr);
|
||||
|
||||
if (Border > 0.0f)
|
||||
{
|
||||
const bool Inject = ActionInfo != nullptr && (ActionInfo->bPressed || ActionInfo->bRepeat);
|
||||
const ImU32 BColor = Inject ? FCogImguiHelper::ToImU32(InjectColor) : FCogImguiHelper::ToImU32(BorderColor);
|
||||
DrawList->AddRect(Position, Position + Size, BColor, RelativeRounding * CanvasSize.x, Flags, Border * CanvasSize.x);
|
||||
}
|
||||
|
||||
DrawList->AddRectFilled(Position, Position + Size, Color, RelativeRounding * CanvasSize.x, Flags);
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogInputWindow_Gamepad::AddStick(const FKey& Key2D, const FKey& KeyBool, bool InvertY, float RelativeAmplitude, const ImVec2& RelativePosition, float RelativeRadius)
|
||||
{
|
||||
ImGui::PushID((void*)(&Key2D));
|
||||
|
||||
ImU32 Color = Input->GetKeyValue(KeyBool) > 0.0f ? FCogImguiHelper::ToImU32(PressedColor) : FCogImguiHelper::ToImU32(ButtonColor);
|
||||
|
||||
FCogInjectActionInfo* ActionInfoBool = Actions.Find(KeyBool);
|
||||
FCogInjectActionInfo* ActionInfo2D = Actions.Find(Key2D);
|
||||
|
||||
FVector Value = Input->GetRawVectorKeyValue(Key2D);
|
||||
if (ActionInfo2D != nullptr && ActionInfo2D->Action != nullptr)
|
||||
{
|
||||
Value = Input->GetActionValue(ActionInfo2D->Action).Get<FVector>();
|
||||
}
|
||||
|
||||
Value.X = FMath::Clamp(Value.X, -1.0f, 1.0f);
|
||||
Value.Y = FMath::Clamp(Value.Y, -1.0f, 1.0f);
|
||||
|
||||
const ImVec2 StickPosition = (CanvasMin + CanvasSize * RelativePosition) + ImVec2(Value.X, -Value.Y * (InvertY ? -1.0f : 1.0f)) * RelativeAmplitude * CanvasSize.x;
|
||||
const float Radius = RelativeRadius * CanvasSize.x;
|
||||
const ImVec2 ButtonPosition = StickPosition - ImVec2(Radius, Radius);
|
||||
const ImVec2 ButtonSize(2 * Radius, 2 * Radius);
|
||||
|
||||
ImGui::SetCursorScreenPos(ButtonPosition);
|
||||
if (ImGui::InvisibleButton("", ButtonSize))
|
||||
{
|
||||
OnButtonClicked(ActionInfoBool);
|
||||
}
|
||||
|
||||
InputContextMenu(Key2D, ActionInfoBool, ActionInfo2D);
|
||||
|
||||
if (Border > 0.0f)
|
||||
{
|
||||
const bool Inject = ActionInfoBool != nullptr && (ActionInfoBool->bPressed || ActionInfoBool->bRepeat);
|
||||
const ImU32 BColor = Inject ? FCogImguiHelper::ToImU32(InjectColor) : FCogImguiHelper::ToImU32(BorderColor);
|
||||
DrawList->AddCircle(StickPosition, Radius, BColor, 0, Border * CanvasSize.x);
|
||||
}
|
||||
|
||||
DrawList->AddCircleFilled(StickPosition, Radius, Color);
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogInputWindow_Gamepad::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
if (GetWorld() == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
||||
if (LocalPlayer == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UEnhancedInputLocalPlayerSubsystem* EnhancedInputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(LocalPlayer);
|
||||
if (EnhancedInputSubsystem == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Input = EnhancedInputSubsystem->GetPlayerInput();
|
||||
if (Input == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ActionsAsset != nullptr && ActionsAsset->MappingContext != nullptr)
|
||||
{
|
||||
if (Actions.Num() == 0)
|
||||
{
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_Left2D);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_LeftX);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_LeftY);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_Right2D);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_RightX);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_RightY);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_LeftTriggerAxis);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_RightTriggerAxis);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_LeftThumbstick);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_RightThumbstick);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_Special_Left);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_Special_Left_X);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_Special_Left_Y);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_Special_Right);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_FaceButton_Bottom);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_FaceButton_Right);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_FaceButton_Left);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_FaceButton_Top);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_LeftShoulder);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_RightShoulder);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_LeftTrigger);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_RightTrigger);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_DPad_Up);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_DPad_Down);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_DPad_Right);
|
||||
Actions.FindOrAdd(EKeys:: Gamepad_DPad_Left);
|
||||
|
||||
for (const FEnhancedActionKeyMapping& Mapping : ActionsAsset->MappingContext->GetMappings())
|
||||
{
|
||||
if (Mapping.Action != nullptr)
|
||||
{
|
||||
FCogInjectActionInfo& ActionInfo = Actions.FindOrAdd(Mapping.Key);
|
||||
ActionInfo.Action = Mapping.Action;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const float AspectRatio = 0.55f;
|
||||
const float StickAmplitude = 0.04f;
|
||||
const float StickRadius = 0.08f;
|
||||
const float StickBaseRadius = 0.1f;
|
||||
const float GamepadRound = 0.15f;
|
||||
const float HandleWidth = 0.26f;
|
||||
const ImVec2 DPadButtonSize(0.08f, 0.08f);
|
||||
const float DpadButtonDistance = 0.075f;
|
||||
const float DpadButtonRounding = 0.1f;
|
||||
const ImVec2 SpecialButtonSize(0.08f, 0.04f);
|
||||
const float SpecialButtonRound = 0.05f;
|
||||
const float SpecialButtonDistance = 0.15f;
|
||||
const float TriggerRound = 0.02f;
|
||||
const ImVec2 TriggerButtonSize(0.08f, 0.05f);
|
||||
const float BumperRound = 0.02f;
|
||||
const ImVec2 BumperButtonSize(0.2f, 0.04f);
|
||||
|
||||
const ImVec2 ContentMin = ImGui::GetCursorScreenPos();
|
||||
const ImVec2 ContentSize = ImGui::GetContentRegionAvail();
|
||||
const ImVec2 ContentMax = ContentMin + ContentSize;
|
||||
const ImVec2 OverlayOffset = ImVec2(0.0f, bShowAsOverlay ? ImGui::GetFrameHeight() : 0.0f);
|
||||
|
||||
const ImVec2 Padding = ImVec2(Border * 0.5f * ContentSize.x, Border * 0.5f * ContentSize.x);
|
||||
CanvasMin = ContentMin + OverlayOffset + Padding;
|
||||
CanvasSize = ImVec2(FMath::Max(ContentSize.x, 50.0f), ContentSize.x * AspectRatio) - (Padding * 2);
|
||||
CanvasMax = CanvasMin + CanvasSize + OverlayOffset;
|
||||
|
||||
DrawList = ImGui::GetWindowDrawList();
|
||||
ImGui::Dummy(bShowAsOverlay ? CanvasMax - CanvasMin : ContentSize);
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
ImGui::Checkbox("Overlay", &bShowAsOverlay);
|
||||
ImGui::Separator();
|
||||
ImGui::Checkbox("Invert Left Stick Y", &bInvertLeftStickY);
|
||||
ImGui::Checkbox("Invert Right Stick Y", &bInvertRightStickY);
|
||||
ImGui::Separator();
|
||||
ImGui::ColorEdit4("Background Color", (float*)&BackgroundColor, ImGuiColorEditFlags_NoInputs);
|
||||
ImGui::ColorEdit4("Border Color", (float*)&BorderColor, ImGuiColorEditFlags_NoInputs);
|
||||
ImGui::ColorEdit4("Button Color", (float*)&ButtonColor, ImGuiColorEditFlags_NoInputs);
|
||||
ImGui::ColorEdit4("Pressed Color", (float*)&PressedColor, ImGuiColorEditFlags_NoInputs);
|
||||
ImGui::ColorEdit4("Inject Color", (float*)&InjectColor, ImGuiColorEditFlags_NoInputs);
|
||||
FCogWindowWidgets::SliderWithReset("Border", &Border, 0.0f, 0.1f, 0.02f, "%0.3f");
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
DrawList->PushClipRect(ContentMin, ContentMax, true);
|
||||
|
||||
const ImVec2 LS_Pos(0.35f, 0.7f);
|
||||
const ImVec2 RS_Pos(0.65f, 0.7f);
|
||||
|
||||
//------------------------------
|
||||
// Triggers
|
||||
//------------------------------
|
||||
AddButton(EKeys::Gamepad_LeftTriggerAxis, ImVec2(0.18f, 0.12f), TriggerButtonSize, ImVec2(0.5f, 1.0f), TriggerRound, ImDrawFlags_RoundCornersTop);
|
||||
AddButton(EKeys::Gamepad_RightTriggerAxis, ImVec2(1.f - 0.18f, 0.12f), TriggerButtonSize, ImVec2(0.5f, 1.0f), TriggerRound, ImDrawFlags_RoundCornersTop);
|
||||
|
||||
//------------------------------
|
||||
// Shoulders
|
||||
//------------------------------
|
||||
AddButton(EKeys::Gamepad_LeftShoulder, ImVec2(0.18f, 0.15f), BumperButtonSize, ImVec2(0.5f, 0.5f), BumperRound, ImDrawFlags_RoundCornersTop);
|
||||
AddButton(EKeys::Gamepad_RightShoulder, ImVec2(1.f - 0.18f, 0.15f), BumperButtonSize, ImVec2(0.5f, 0.5f), BumperRound, ImDrawFlags_RoundCornersTop);
|
||||
|
||||
//------------------------------
|
||||
// Gamepad
|
||||
//------------------------------
|
||||
if (Border > 0.0f)
|
||||
{
|
||||
DrawList->AddRect(CanvasMin + CanvasSize * ImVec2(0.0f, 0.16f), CanvasMin + CanvasSize * ImVec2(1.0f, 0.7f), FCogImguiHelper::ToImU32(BorderColor), GamepadRound * CanvasSize.x, 0, Border * CanvasSize.x);
|
||||
DrawList->AddRect(CanvasMin + CanvasSize * ImVec2(0.0f, 0.16f), CanvasMin + CanvasSize * ImVec2(HandleWidth, 1.0f), FCogImguiHelper::ToImU32(BorderColor), GamepadRound * CanvasSize.x, 0, Border * CanvasSize.x);
|
||||
DrawList->AddRect(CanvasMin + CanvasSize * ImVec2(1.0f - HandleWidth, 0.16f), CanvasMin + CanvasSize * ImVec2(1.0f, 1.0f), FCogImguiHelper::ToImU32(BorderColor), GamepadRound * CanvasSize.x, 0, Border * CanvasSize.x);
|
||||
|
||||
DrawList->AddCircle(CanvasMin + CanvasSize * LS_Pos, StickBaseRadius* CanvasSize.x, FCogImguiHelper::ToImU32(BorderColor), 0, Border* CanvasSize.x);
|
||||
DrawList->AddCircle(CanvasMin + CanvasSize * RS_Pos, StickBaseRadius* CanvasSize.x, FCogImguiHelper::ToImU32(BorderColor), 0, Border* CanvasSize.x);
|
||||
}
|
||||
|
||||
DrawList->AddRectFilled(CanvasMin + CanvasSize * ImVec2(0.0f, 0.16f), CanvasMin + CanvasSize * ImVec2(1.0f, 0.7f), FCogImguiHelper::ToImU32(BackgroundColor), GamepadRound * CanvasSize.x);
|
||||
DrawList->AddRectFilled(CanvasMin + CanvasSize * ImVec2(0.0f, 0.16f), CanvasMin + CanvasSize * ImVec2(HandleWidth, 1.0f), FCogImguiHelper::ToImU32(BackgroundColor), GamepadRound * CanvasSize.x);
|
||||
DrawList->AddRectFilled(CanvasMin + CanvasSize * ImVec2(1.0f - HandleWidth, 0.16f), CanvasMin + CanvasSize * ImVec2(1.0f, 1.0f), FCogImguiHelper::ToImU32(BackgroundColor), GamepadRound * CanvasSize.x);
|
||||
|
||||
DrawList->AddCircleFilled(CanvasMin + CanvasSize * LS_Pos, StickBaseRadius* CanvasSize.x, FCogImguiHelper::ToImU32(BackgroundColor));
|
||||
DrawList->AddCircleFilled(CanvasMin + CanvasSize * RS_Pos, StickBaseRadius* CanvasSize.x, FCogImguiHelper::ToImU32(BackgroundColor));
|
||||
|
||||
//------------------------------
|
||||
// Sticks
|
||||
//------------------------------
|
||||
AddStick(EKeys::Gamepad_Left2D, EKeys::Gamepad_LeftThumbstick, bInvertLeftStickY, StickAmplitude, LS_Pos, StickRadius);
|
||||
AddStick(EKeys::Gamepad_Right2D, EKeys::Gamepad_RightThumbstick, bInvertRightStickY, StickAmplitude, RS_Pos, StickRadius);
|
||||
|
||||
//------------------------------
|
||||
// DPad Buttons
|
||||
//------------------------------
|
||||
const ImVec2 DPad_Pos(0.15f, 0.44f);
|
||||
AddButton(EKeys::Gamepad_DPad_Up, DPad_Pos + ImVec2(0.0f, -DpadButtonDistance / AspectRatio), DPadButtonSize, ImVec2(0.5f, 0.5f), DpadButtonRounding);
|
||||
AddButton(EKeys::Gamepad_DPad_Down, DPad_Pos + ImVec2(0.0f, DpadButtonDistance / AspectRatio), DPadButtonSize, ImVec2(0.5f, 0.5f), DpadButtonRounding);
|
||||
AddButton(EKeys::Gamepad_DPad_Left, DPad_Pos + ImVec2(-DpadButtonDistance, 0.0f), DPadButtonSize, ImVec2(0.5f, 0.5f), DpadButtonRounding);
|
||||
AddButton(EKeys::Gamepad_DPad_Right, DPad_Pos + ImVec2(DpadButtonDistance, 0.0f), DPadButtonSize, ImVec2(0.5f, 0.5f), DpadButtonRounding);
|
||||
|
||||
//------------------------------
|
||||
// Face Buttons
|
||||
//------------------------------
|
||||
const ImVec2 Face_Pos(1.0f - 0.15f, 0.44f);
|
||||
AddButton(EKeys::Gamepad_FaceButton_Top, Face_Pos + ImVec2(0.0f, -DpadButtonDistance / AspectRatio), DPadButtonSize, ImVec2(0.5f, 0.5f), DpadButtonRounding);
|
||||
AddButton(EKeys::Gamepad_FaceButton_Bottom, Face_Pos + ImVec2(0.0f, DpadButtonDistance / AspectRatio), DPadButtonSize, ImVec2(0.5f, 0.5f), DpadButtonRounding);
|
||||
AddButton(EKeys::Gamepad_FaceButton_Left, Face_Pos + ImVec2(-DpadButtonDistance, 0.0f), DPadButtonSize, ImVec2(0.5f, 0.5f), DpadButtonRounding);
|
||||
AddButton(EKeys::Gamepad_FaceButton_Right, Face_Pos + ImVec2(DpadButtonDistance, 0.0f), DPadButtonSize, ImVec2(0.5f, 0.5f), DpadButtonRounding);
|
||||
|
||||
//------------------------------
|
||||
// Special Buttons
|
||||
//------------------------------
|
||||
AddButton(EKeys::Gamepad_Special_Left, ImVec2(0.5f - SpecialButtonDistance * 0.5f, 0.35f), SpecialButtonSize, ImVec2(0.5f, 0.5f), SpecialButtonRound);
|
||||
AddButton(EKeys::Gamepad_Special_Right, ImVec2(0.5f + SpecialButtonDistance * 0.5f, 0.35f), SpecialButtonSize, ImVec2(0.5f, 0.5f), SpecialButtonRound);
|
||||
|
||||
DrawList->PopClipRect();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogInputWindow_Gamepad::RenderTick(float DeltaSeconds)
|
||||
{
|
||||
Super::RenderTick(DeltaSeconds);
|
||||
|
||||
if (GetWorld() == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
||||
if (LocalPlayer == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UEnhancedInputLocalPlayerSubsystem* EnhancedInput = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(LocalPlayer);
|
||||
if (EnhancedInput == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool IsTimeToRepeat = false;
|
||||
float WorldTime = GetWorld()->GetTimeSeconds();
|
||||
if (RepeatTime < WorldTime)
|
||||
{
|
||||
RepeatTime = WorldTime + RepeatPeriod;
|
||||
IsTimeToRepeat = true;
|
||||
}
|
||||
|
||||
for (auto& Entry : Actions)
|
||||
{
|
||||
FCogInjectActionInfo& ActionInfo = Entry.Value;
|
||||
ActionInfo.Inject(*EnhancedInput, IsTimeToRepeat);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
class UInputAction;
|
||||
class UEnhancedInputLocalPlayerSubsystem;
|
||||
|
||||
struct FCogInjectActionInfo
|
||||
{
|
||||
const UInputAction* Action = nullptr;
|
||||
bool bPressed = false;
|
||||
bool bRepeat = false;
|
||||
float X = 0.0f;
|
||||
float Y = 0.0f;
|
||||
float Z = 0.0f;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
bPressed = false;
|
||||
bRepeat = false;
|
||||
X = 0.0f;
|
||||
Y = 0.0f;
|
||||
Z = 0.0f;
|
||||
}
|
||||
|
||||
void Inject(UEnhancedInputLocalPlayerSubsystem& EnhancedInput, bool IsTimeToRepeat);
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogInputDataAsset_Actions.generated.h"
|
||||
|
||||
class UInputAction;
|
||||
class UInputMappingContext;
|
||||
|
||||
UCLASS(Blueprintable)
|
||||
class COGINPUT_API UCogInputDataAsset_Actions : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogInputDataAsset_Actions() {}
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
TObjectPtr<const UInputMappingContext> MappingContext;
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class COGINPUT_API FCogInputModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
static inline FCogInputModule& Get()
|
||||
{
|
||||
return FModuleManager::LoadModuleChecked<FCogInputModule>("CogInput");
|
||||
}
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
|
||||
private:
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogInjectActionInfo.h"
|
||||
#include "CogInputWindow_Actions.generated.h"
|
||||
|
||||
class UInputAction;
|
||||
class UCogInputDataAsset_Actions;
|
||||
|
||||
UCLASS()
|
||||
class COGINPUT_API UCogInputWindow_Actions : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogInputWindow_Actions();
|
||||
|
||||
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
|
||||
virtual void RenderContent() override;
|
||||
virtual void RenderTick(float DeltaSeconds) override;
|
||||
|
||||
TWeakObjectPtr<UCogInputDataAsset_Actions> ActionsAsset;
|
||||
|
||||
private:
|
||||
|
||||
float RepeatPeriod = 0.5f;
|
||||
float RepeatTime = 0.0f;
|
||||
TArray<FCogInjectActionInfo> Actions;
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogInputWindow_Gamepad.generated.h"
|
||||
|
||||
class UEnhancedPlayerInput;
|
||||
struct ImDrawList;
|
||||
|
||||
UCLASS(Config = Cog)
|
||||
class COGINPUT_API UCogInputWindow_Gamepad : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogInputWindow_Gamepad();
|
||||
|
||||
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
|
||||
virtual void RenderContent() override;
|
||||
virtual void RenderTick(float DeltaSeconds) override;
|
||||
|
||||
TWeakObjectPtr<UCogInputDataAsset_Actions> ActionsAsset;
|
||||
|
||||
private:
|
||||
|
||||
void AddButton(const FKey& Key, const ImVec2& Position, const ImVec2& Size, const ImVec2& Alignment, float Rounding, ImDrawFlags Flags = 0);
|
||||
void AddStick(const FKey& Key2D, const FKey& KeyBool, bool InvertY, float Amplitude, const ImVec2& Position, float Radius);
|
||||
void InputContextMenu(const FKey& Key, FCogInjectActionInfo* ActionInfoBool, FCogInjectActionInfo* ActionInfo2D);
|
||||
void OnButtonClicked(FCogInjectActionInfo* ActionInfo);
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool bShowAsOverlay = false;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool bInvertRightStickY = false;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool bInvertLeftStickY = false;
|
||||
|
||||
UPROPERTY(Config)
|
||||
FVector4f BackgroundColor = FVector4f(0.03f, 0.03f, 0.03f, 1.0f);
|
||||
|
||||
UPROPERTY(Config)
|
||||
FVector4f ButtonColor = FVector4f(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
|
||||
UPROPERTY(Config)
|
||||
FVector4f BorderColor = FVector4f(0.03f, 0.03f, 0.03f, 1.0f);
|
||||
|
||||
UPROPERTY(Config)
|
||||
FVector4f PressedColor = FVector4f(0.6f, 0.6f, 0.6f, 1.0f);
|
||||
|
||||
UPROPERTY(Config)
|
||||
FVector4f InjectColor = FVector4f(1.0f, 0.5f, 0.0f, 0.5f);
|
||||
|
||||
UPROPERTY(Config)
|
||||
float Border = 0.02f;
|
||||
|
||||
TMap<FKey, FCogInjectActionInfo> Actions;
|
||||
|
||||
UEnhancedPlayerInput* Input = nullptr;
|
||||
ImDrawList* DrawList = nullptr;
|
||||
float RepeatPeriod = 0.5f;
|
||||
float RepeatTime = 0.0f;
|
||||
ImVec2 CanvasMin;
|
||||
ImVec2 CanvasSize;
|
||||
ImVec2 CanvasMax;
|
||||
};
|
||||
Reference in New Issue
Block a user