diff --git a/Content/Widgets/BP_CustomButton.uasset b/Content/Widgets/BP_CustomButton.uasset index 45d0578..4690b8c 100644 --- a/Content/Widgets/BP_CustomButton.uasset +++ b/Content/Widgets/BP_CustomButton.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c2b2e8eab0f6833f74989ee9172003b93541f069f2e8d85963fb2e5a6a33959 -size 28820 +oid sha256:e8f04235f8da7980ddd63ba79a27454b56e01ba83db2f926e4c9b0005f268c49 +size 28939 diff --git a/Content/Widgets/MainMenu/BP_MainMenuWidget.uasset b/Content/Widgets/MainMenu/BP_MainMenuWidget.uasset index e28ea30..cf7b21a 100644 --- a/Content/Widgets/MainMenu/BP_MainMenuWidget.uasset +++ b/Content/Widgets/MainMenu/BP_MainMenuWidget.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a059f60b1ef50c6b9c1c8295674aec3c7efffb93f479b632c3f0516bd582ebbe -size 40728 +oid sha256:123b21415cb1743d0f9a0a01e67f7b8badf595e6bfb1fa8e499eefc7fa9248e1 +size 36010 diff --git a/Source/vampires/DetectGamepad.cpp b/Source/vampires/DetectGamepad.cpp new file mode 100644 index 0000000..1289c7e --- /dev/null +++ b/Source/vampires/DetectGamepad.cpp @@ -0,0 +1,16 @@ +// Louis Hobbs | 2024-2025 + + +#include "DetectGamepad.h" + +bool UDetectGamepad::IsControllerConnected() +{ + TSharedPtr Game = FSlateApplication::Get().GetPlatformApplication(); + + if (Game.Get() != nullptr && Game->IsGamepadAttached()) + { + return true; + } + + return false; +} diff --git a/Source/vampires/DetectGamepad.h b/Source/vampires/DetectGamepad.h index 9028502..097e3a3 100644 --- a/Source/vampires/DetectGamepad.h +++ b/Source/vampires/DetectGamepad.h @@ -13,4 +13,9 @@ UCLASS() class VAMPIRES_API UDetectGamepad : public UBlueprintFunctionLibrary { GENERATED_BODY() + +public: + + UFUNCTION(BlueprintCallable, Category = "DetectGamepad") + static bool IsControllerConnected(); }; diff --git a/Source/vampires/Widgets/CustomButton.cpp b/Source/vampires/Widgets/CustomButton.cpp index 0630035..4bc563a 100644 --- a/Source/vampires/Widgets/CustomButton.cpp +++ b/Source/vampires/Widgets/CustomButton.cpp @@ -5,16 +5,19 @@ #include "Components/Button.h" #include "Components/TextBlock.h" +#include "Kismet/GameplayStatics.h" void UCustomButton::NativeConstruct() { Super::NativeConstruct(); + SetIsFocusable(true); + ButtonBody->OnClicked.AddUniqueDynamic(this, &UCustomButton::OnButtonClicked); ButtonBody->OnPressed.AddUniqueDynamic(this, &UCustomButton::OnButtonPressed); ButtonBody->OnReleased.AddUniqueDynamic(this, &UCustomButton::OnButtonReleased); ButtonBody->OnHovered.AddUniqueDynamic(this, &UCustomButton::OnButtonHovered); - ButtonBody->OnUnhovered.AddUniqueDynamic(this, &UCustomButton::OnButtonHovered); + ButtonBody->OnUnhovered.AddUniqueDynamic(this, &UCustomButton::OnButtonUnhovered); TextBlock->SetText(ButtonText); } @@ -34,19 +37,53 @@ TObjectPtr UCustomButton::GetTextBlock() void UCustomButton::OnButtonClicked() { OnClicked.Broadcast(); + + if (ButtonClickedSound) + { + UGameplayStatics::PlaySound2D(GetWorld(), ButtonClickedSound); + } } void UCustomButton::OnButtonPressed() { OnPressed.Broadcast(); + + if (ButtonPressedSound) + { + UGameplayStatics::PlaySound2D(GetWorld(), ButtonPressedSound); + } } void UCustomButton::OnButtonReleased() { OnReleased.Broadcast(); + + if (ButtonReleasedSound) + { + UGameplayStatics::PlaySound2D(GetWorld(), ButtonReleasedSound); + } } void UCustomButton::OnButtonHovered() { OnHovered.Broadcast(); + + if (ButtonHoveredSound) + { + UGameplayStatics::PlaySound2D(GetWorld(), ButtonHoveredSound); + } + + TextBlock->SetColorAndOpacity(FSlateColor(ButtonHoveredTextColor)); +} + +void UCustomButton::OnButtonUnhovered() +{ + OnUnhovered.Broadcast(); + + if (ButtonUnhoveredSound) + { + UGameplayStatics::PlaySound2D(GetWorld(), ButtonUnhoveredSound); + } + + TextBlock->SetColorAndOpacity(FSlateColor(ButtonUnhoveredTextColor)); } diff --git a/Source/vampires/Widgets/CustomButton.h b/Source/vampires/Widgets/CustomButton.h index c6c3d7c..a18bbfa 100644 --- a/Source/vampires/Widgets/CustomButton.h +++ b/Source/vampires/Widgets/CustomButton.h @@ -35,9 +35,33 @@ public: UPROPERTY(BlueprintAssignable) FOnButtonHoverEventCustom OnHovered; + + UPROPERTY(BlueprintAssignable) + FOnButtonHoverEventCustom OnUnhovered; - UPROPERTY(EditAnywhere, BlueprintReadOnly) + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Button Settings | Text") FText ButtonText = FText::FromString("Default"); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button Settings | Color") + FLinearColor ButtonHoveredTextColor = {0, 1, 0, 1}; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button Settings | Color") + FLinearColor ButtonUnhoveredTextColor = {1, 1, 1, 1}; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button Settings | Sound") + TObjectPtr ButtonClickedSound; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button Settings | Sound") + TObjectPtr ButtonPressedSound; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button Settings | Sound") + TObjectPtr ButtonReleasedSound; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button Settings | Sound") + TObjectPtr ButtonHoveredSound; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button Settings | Sound") + TObjectPtr ButtonUnhoveredSound; private: UPROPERTY(meta = (BindWidget)) @@ -68,4 +92,7 @@ private: UFUNCTION() void OnButtonHovered(); + + UFUNCTION() + void OnButtonUnhovered(); }; diff --git a/Source/vampires/Widgets/MainMenuWidget.cpp b/Source/vampires/Widgets/MainMenuWidget.cpp index eb82a4b..8004850 100644 --- a/Source/vampires/Widgets/MainMenuWidget.cpp +++ b/Source/vampires/Widgets/MainMenuWidget.cpp @@ -3,6 +3,7 @@ #include "MainMenuWidget.h" +#include "CustomButton.h" #include "SelectWeaponWidget.h" #include "Blueprint/WidgetBlueprintLibrary.h" #include "Components/Button.h" @@ -15,37 +16,36 @@ void UMainMenuWidget::NativeConstruct() if (NewGameButton) { NewGameButton->OnClicked.AddUniqueDynamic(this, &UMainMenuWidget::NewGameButtonOnClicked); - NewGameButton->OnHovered.AddUniqueDynamic(this, &UMainMenuWidget::NewGameButtonOnHovered); - NewGameButton->OnUnhovered.AddUniqueDynamic(this, &UMainMenuWidget::NewGameButtonOnUnhovered); } if (OptionsButton) { OptionsButton->OnClicked.AddUniqueDynamic(this, &UMainMenuWidget::OptionsButtonOnClicked); - OptionsButton->OnHovered.AddUniqueDynamic(this, &UMainMenuWidget::OptionsButtonOnHovered); - OptionsButton->OnUnhovered.AddUniqueDynamic(this, &UMainMenuWidget::OptionsButtonOnUnhovered); } if (QuitButton) { QuitButton->OnClicked.AddUniqueDynamic(this, &UMainMenuWidget::QuitButtonOnClicked); - QuitButton->OnHovered.AddUniqueDynamic(this, &UMainMenuWidget::QuitButtonOnHovered); - QuitButton->OnUnhovered.AddUniqueDynamic(this, &UMainMenuWidget::QuitButtonOnUnhovered); } QuitButton->SetIsEnabled(false); if (APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0)) { - UWidgetBlueprintLibrary::SetInputMode_UIOnlyEx(PlayerController, this, EMouseLockMode::LockAlways); + UWidgetBlueprintLibrary::SetInputMode_UIOnlyEx(PlayerController, NewGameButton, EMouseLockMode::LockAlways); PlayerController->bShowMouseCursor = true; } } +FReply UMainMenuWidget::NativeOnMouseButtonUp(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) +{ + NewGameButton->SetKeyboardFocus(); + + return Super::NativeOnMouseButtonUp(InGeometry, InMouseEvent); +} + void UMainMenuWidget::NewGameButtonOnClicked() { - PlayClickedSound(); - if (NewGameMenuWidget) { RemoveFromParent(); @@ -62,8 +62,6 @@ void UMainMenuWidget::NewGameButtonOnClicked() void UMainMenuWidget::OptionsButtonOnClicked() { - PlayClickedSound(); - if (OptionsMenuWidget) { RemoveFromParent(); @@ -80,46 +78,8 @@ void UMainMenuWidget::OptionsButtonOnClicked() void UMainMenuWidget::QuitButtonOnClicked() { - PlayClickedSound(); - // TODO: Add platform specific Exit requests // This is not a bit deal for the moment as we are only building for windows // For some reason the generic version does not work the same as FWindowsPlatformMisc FWindowsPlatformMisc::RequestExit(false); -} - -void UMainMenuWidget::NewGameButtonOnHovered() -{ - PlayHoveredSound(); - SetTextBlockHovered(NewGameTextBlock); -} - -void UMainMenuWidget::NewGameButtonOnUnhovered() -{ - PlayUnhoveredSound(); - SetTextBlockUnhovered(NewGameTextBlock); -} - -void UMainMenuWidget::OptionsButtonOnHovered() -{ - PlayHoveredSound(); - SetTextBlockHovered(OptionsTextBlock); -} - -void UMainMenuWidget::OptionsButtonOnUnhovered() -{ - PlayUnhoveredSound(); - SetTextBlockUnhovered(OptionsTextBlock); -} - -void UMainMenuWidget::QuitButtonOnHovered() -{ - PlayHoveredSound(); - SetTextBlockHovered(QuitTextBlock); -} - -void UMainMenuWidget::QuitButtonOnUnhovered() -{ - PlayUnhoveredSound(); - SetTextBlockUnhovered(QuitTextBlock); -} +} \ No newline at end of file diff --git a/Source/vampires/Widgets/MainMenuWidget.h b/Source/vampires/Widgets/MainMenuWidget.h index 2084eed..eff791d 100644 --- a/Source/vampires/Widgets/MainMenuWidget.h +++ b/Source/vampires/Widgets/MainMenuWidget.h @@ -6,32 +6,24 @@ #include "VampireInteractiveWidget.h" #include "MainMenuWidget.generated.h" +class UCustomButton; class UButton; /** * */ UCLASS() -class VAMPIRES_API UMainMenuWidget : public UVampireInteractiveWidget +class VAMPIRES_API UMainMenuWidget : public UUserWidget { GENERATED_BODY() UPROPERTY(meta = (BindWidget)) - TObjectPtr NewGameButton; + TObjectPtr NewGameButton; UPROPERTY(meta = (BindWidget)) - TObjectPtr NewGameTextBlock; + TObjectPtr OptionsButton; UPROPERTY(meta = (BindWidget)) - TObjectPtr OptionsButton; - - UPROPERTY(meta = (BindWidget)) - TObjectPtr OptionsTextBlock; - - UPROPERTY(meta = (BindWidget)) - TObjectPtr QuitButton; - - UPROPERTY(meta = (BindWidget)) - TObjectPtr QuitTextBlock; + TObjectPtr QuitButton; UPROPERTY(EditDefaultsOnly, Category = "Widget Settings | New Game") TSubclassOf NewGameMenuWidget; @@ -45,6 +37,9 @@ class VAMPIRES_API UMainMenuWidget : public UVampireInteractiveWidget public: virtual void NativeConstruct() override; +protected: + virtual FReply NativeOnMouseButtonUp(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override; + private: UFUNCTION() void NewGameButtonOnClicked(); @@ -54,22 +49,4 @@ private: UFUNCTION() void QuitButtonOnClicked(); - - UFUNCTION() - void NewGameButtonOnHovered(); - - UFUNCTION() - void NewGameButtonOnUnhovered(); - - UFUNCTION() - void OptionsButtonOnHovered(); - - UFUNCTION() - void OptionsButtonOnUnhovered(); - - UFUNCTION() - void QuitButtonOnHovered(); - - UFUNCTION() - void QuitButtonOnUnhovered(); }; diff --git a/Source/vampires/Widgets/VampireInteractiveWidget.cpp b/Source/vampires/Widgets/VampireInteractiveWidget.cpp index 6410f23..6293925 100644 --- a/Source/vampires/Widgets/VampireInteractiveWidget.cpp +++ b/Source/vampires/Widgets/VampireInteractiveWidget.cpp @@ -6,6 +6,19 @@ #include "Components/TextBlock.h" #include "GameFramework/GameUserSettings.h" #include "Kismet/GameplayStatics.h" +#include "vampires/DetectGamepad.h" + +void UVampireInteractiveWidget::NativeTick(const FGeometry& MyGeometry, float InDeltaTime) +{ + Super::NativeTick(MyGeometry, InDeltaTime); + + GamepadConnected = UDetectGamepad::IsControllerConnected(); +} + +FReply UVampireInteractiveWidget::NativeOnMouseButtonUp(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) +{ + return Super::NativeOnMouseButtonUp(InGeometry, InMouseEvent); +} void UVampireInteractiveWidget::SetReturnScreen(UUserWidget* UserWidget) { diff --git a/Source/vampires/Widgets/VampireInteractiveWidget.h b/Source/vampires/Widgets/VampireInteractiveWidget.h index 9b9ee10..5588050 100644 --- a/Source/vampires/Widgets/VampireInteractiveWidget.h +++ b/Source/vampires/Widgets/VampireInteractiveWidget.h @@ -6,6 +6,7 @@ #include "Blueprint/UserWidget.h" #include "VampireInteractiveWidget.generated.h" +class UButton; class UTextBlock; /** * @@ -31,10 +32,19 @@ protected: UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Widget Settings | Sound") TObjectPtr ButtonClickedSound; + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Widget Settings") + TArray> InteractableButtons; + protected: UPROPERTY() TObjectPtr PreviousScreen; + bool GamepadConnected = false; + + virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override; + + virtual FReply NativeOnMouseButtonUp(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override; + public: UFUNCTION() void SetReturnScreen(UUserWidget* UserWidget); diff --git a/Source/vampires/vampires.Build.cs b/Source/vampires/vampires.Build.cs index 850ca97..8e53104 100644 --- a/Source/vampires/vampires.Build.cs +++ b/Source/vampires/vampires.Build.cs @@ -10,7 +10,7 @@ public class vampires : ModuleRules PublicDependencyModuleNames.AddRange(new[] { - "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "Paper2D", "Niagara", "SlateCore", "RHI" + "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "Paper2D", "Niagara", "SlateCore", "RHI", "Slate" }); PrivateDependencyModuleNames.AddRange(new string[] { });