From a58ef0abcdbf5fa2efacacd84680c4e6fb1f6206 Mon Sep 17 00:00:00 2001 From: Oleg Petruny Date: Thu, 5 Sep 2024 18:43:40 +0200 Subject: [PATCH] QTE, crash fixes, bug fixes, optimizations, warnings clearing --- Config/DefaultEngine.ini | 2 +- Config/DefaultInput.ini | 1 + .../Blueprints/BP_CustomGameInstance.uasset | 3 + .../Blueprints/Characters/BP_Player.uasset | 4 +- .../GameModes/BP_MainGameMode.uasset | Bin 15252 -> 130 bytes .../Other/BP_CustomGameInstance.uasset | Bin 6198 -> 0 bytes .../QuickTimeEventTest/BP_Test_QTEHold.uasset | 3 + .../BP_Test_QTEMulti.uasset | 3 + .../BP_Test_QTESingle.uasset | 3 + Content/Levels/Test/L_Test.umap | 4 +- .../Test/Sequences/Seq_TestCutscene.uasset | Bin 28305 -> 129 bytes .../Test/Sequences/Seq_Test_Ball.uasset | 3 + .../Test/Sequences/Seq_Test_Cutscene.uasset | 3 + .../ImportTest/M_ImportTest_BarelWood.uasset | Bin 13533 -> 130 bytes .../M_ImportTest_BarrelRings.uasset | Bin 10948 -> 130 bytes .../ImportTest/SM_ImportTest_Barrel.uasset | Bin 59070 -> 130 bytes Content/UI/BP_MainWidgetManager.uasset | 4 +- .../UI_QuickTimeEventHold.uasset | 3 + .../UI_QuickTimeEventManager.uasset | 3 + .../UI_QuickTimeEventMultiPress.uasset | 3 + .../UI_QuickTimeEventSinglePress.uasset | 3 + Source/Lost_Edge/Private/CommonFunctions.cpp | 76 +++++++- Source/Lost_Edge/Private/CommonFunctions.h | 21 ++ Source/Lost_Edge/Private/Levels/Level3.cpp | 2 - Source/Lost_Edge/Private/Levels/Level4.cpp | 2 - Source/Lost_Edge/Private/Levels/Level5.cpp | 2 - Source/Lost_Edge/Private/Levels/LevelBase.cpp | 2 +- Source/Lost_Edge/Private/MainGameModeBase.cpp | 32 +-- Source/Lost_Edge/Private/MainGameModeBase.h | 13 +- Source/Lost_Edge/Private/PlayerBase.cpp | 22 ++- Source/Lost_Edge/Private/PlayerBase.h | 8 + Source/Lost_Edge/Private/QuickTimeEvent.cpp | 182 ++++++++++++++++++ Source/Lost_Edge/Private/QuickTimeEvent.h | 95 +++++++++ .../Private/Widgets/AdvanceButton.cpp | 64 ------ .../Lost_Edge/Private/Widgets/AdvanceButton.h | 51 ----- .../Private/Widgets/QuickTimeEventWidget.cpp | 58 ++++++ .../Private/Widgets/QuickTimeEventWidget.h | 54 ++++++ .../Widgets/QuickTimeEventWidgetManager.cpp | 77 ++++++++ .../Widgets/QuickTimeEventWidgetManager.h | 37 ++++ .../Private/Widgets/WidgetsManager.cpp | 25 +++ .../Private/Widgets/WidgetsManager.h | 9 + .../WorldDilationResponsiveUserWidget.cpp | 81 ++++++++ .../WorldDilationResponsiveUserWidget.h | 25 +++ 43 files changed, 828 insertions(+), 155 deletions(-) create mode 100644 Content/Blueprints/BP_CustomGameInstance.uasset delete mode 100644 Content/Blueprints/Other/BP_CustomGameInstance.uasset create mode 100644 Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEHold.uasset create mode 100644 Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEMulti.uasset create mode 100644 Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTESingle.uasset create mode 100644 Content/Levels/Test/Sequences/Seq_Test_Ball.uasset create mode 100644 Content/Levels/Test/Sequences/Seq_Test_Cutscene.uasset create mode 100644 Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventHold.uasset create mode 100644 Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventManager.uasset create mode 100644 Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventMultiPress.uasset create mode 100644 Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventSinglePress.uasset create mode 100644 Source/Lost_Edge/Private/QuickTimeEvent.cpp create mode 100644 Source/Lost_Edge/Private/QuickTimeEvent.h delete mode 100644 Source/Lost_Edge/Private/Widgets/AdvanceButton.cpp delete mode 100644 Source/Lost_Edge/Private/Widgets/AdvanceButton.h create mode 100644 Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.cpp create mode 100644 Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.h create mode 100644 Source/Lost_Edge/Private/Widgets/QuickTimeEventWidgetManager.cpp create mode 100644 Source/Lost_Edge/Private/Widgets/QuickTimeEventWidgetManager.h create mode 100644 Source/Lost_Edge/Private/Widgets/WorldDilationResponsiveUserWidget.cpp create mode 100644 Source/Lost_Edge/Private/Widgets/WorldDilationResponsiveUserWidget.h diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini index 78a206a..4390a71 100644 --- a/Config/DefaultEngine.ini +++ b/Config/DefaultEngine.ini @@ -5,7 +5,7 @@ GameDefaultMap=/Game/Levels/Test/L_Test.L_Test EditorStartupMap=/Game/Levels/Test/L_Test.L_Test bUseSplitscreen=False GlobalDefaultGameMode=/Game/Blueprints/GameModes/BP_MainGameMode.BP_MainGameMode_C -GameInstanceClass=/Game/Blueprints/Other/BP_CustomGameInstance.BP_CustomGameInstance_C +GameInstanceClass=/Game/Blueprints/BP_CustomGameInstance.BP_CustomGameInstance_C [/Script/WindowsTargetPlatform.WindowsTargetSettings] DefaultGraphicsRHI=DefaultGraphicsRHI_DX12 diff --git a/Config/DefaultInput.ini b/Config/DefaultInput.ini index ca152e1..19855f7 100644 --- a/Config/DefaultInput.ini +++ b/Config/DefaultInput.ini @@ -78,6 +78,7 @@ DefaultViewportMouseCaptureMode=CapturePermanently_IncludingInitialMouseDown DefaultViewportMouseLockMode=LockOnCapture FOVScale=0.011110 DoubleClickTime=0.200000 ++ActionMappings=(ActionName="AnyKey",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=AnyKey) DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput DefaultInputComponentClass=/Script/EnhancedInput.EnhancedInputComponent DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks diff --git a/Content/Blueprints/BP_CustomGameInstance.uasset b/Content/Blueprints/BP_CustomGameInstance.uasset new file mode 100644 index 0000000..005913a --- /dev/null +++ b/Content/Blueprints/BP_CustomGameInstance.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0de06017dc169ae344130998119b1fef2cea5199f48e6e024474df02958eb1dd +size 6180 diff --git a/Content/Blueprints/Characters/BP_Player.uasset b/Content/Blueprints/Characters/BP_Player.uasset index df20519..d247c0e 100644 --- a/Content/Blueprints/Characters/BP_Player.uasset +++ b/Content/Blueprints/Characters/BP_Player.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dbb801ad73a6c2185db8942117e3b658a1f4f932d5f5f6da2b6b967a7585bf42 -size 490439 +oid sha256:90fcefd43bc5ac2aa88805027849546be24f36ef62faa0274c6a763687ec1495 +size 490589 diff --git a/Content/Blueprints/GameModes/BP_MainGameMode.uasset b/Content/Blueprints/GameModes/BP_MainGameMode.uasset index c1ba1d7e33d3381910119c52223746106790526c..a5c46c6ade067ed57d688cb072a97bf703c49d44 100644 GIT binary patch literal 130 zcmWN?NfN>!5CFh?UcmN=Y0rRyrbYrwNNRl3@s^BQcSUFu%#f90YJzGi`6{r;ZNl9A@ghvv*=XdAcnUO8a zD$cim^xNyt^El_+^SbArduHb9;NLF&-Y0{DgPmVuY|>ebeMo1tN%Vi&!K+uFtaxYq zpLViGw)HMuIF4YAn_k~oQR$w(W#g8|Z$A2Xd?LYiU3f|7&br_OZ@n^O-*0|?Z0at8 z-SFylk^4*Qj=a~fe&6CpAA6>sU~^w>-t$b|!u$La=G^hC9S4+U1bfH*+Wx6^H(mPJ zwnGoxyZ-bl$h|^8b!fY9zxVL@yKhfAFPXW3V4kb*e$8L=^!)oCn7(shX7F$!!H$Rb zzjM@c$A^<&cimh1q<_U?f`tPU-`!9>Z*%88(0OISN?+;9l9j97MI~;( zuehYx>s?j6%I_-j6?<2fdWpnnu;UNsGB%UWt<<^pD+Z%&blye(_tO8wPmXuKd2Ws8 z>4(=|bH(YOEep*FPJVXp-1RpeUelX*;NxZp1|KMLHYwy_FSt%Qrqf+sUQ1a~UZWaS zm8817XvIp7XRK}ICnMmg6K^kfe()?V&N`p5&b0sD#=N#G@xsVYNbn!vLDS% zbescFG+K)xVuKgF>mi4-(nLZTs848dHK7l%%KdLgz_5$xw0<9XM2~1OHu(OzzrPsZ zYPDMl4AiP>uvx25CA!t7&1$q!4JFyP9{k!`@H69~JQWGDLlb7TTx5q<#&k6iQ=%*4pMv^Hd8riCPwVt>ZQ)4>2|Hf6X!z*4zSG%>u0Q-2`9WQ{h1k_Rl zvv022Fa?|?ut`hkkytl7f7+=&Wh%yu0toFpC zB$55czPUdI1D_gFQc<1VFsQAYX5E)3lz14U#SZ-LNS_T+uk^^-urz6d)r>Qe=P|x%JK?9-2g~EEv(%pic{=U{hr*q_HPE z&N~Sq2FeJ%dPNVjmrC#14nAdlMC#<~vLl~f`q0?~Q@5xAcI~lKvoL)AsHW)VNS*xA zTc_bCe<~J0c=3)&=3BD(a`;JtDXi3l8VjgwZ~LhWz!Uj|RV_I3pXgmqrY6XXLBkWf zCT?iP?B>jP?A^QL7k#`J0?}LlSs1-4B0*J*V}xeGjH>^64sMcR*{UQWN>^0nF1dVg z(rK7SNK^N{udG^+XsT9{db+EUY|8AjeuZgQqxN*E3C`k{OCNp|@nnGN6|zTX+m2p$ z8RE$RT4rv0^oc7l1e7vUQI*n>qDT5v?&wu;)HmFH;hTG}g1ZrHMnai6rMwMRH7R{+ur;Fg*M&k!RcF`!+j~9}-mYmqr9E1T zywEY@)_

`aoFiQP|*@Heq$xskhGuRosV7oAYK(Nq&d+Of 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 diff --git a/Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEHold.uasset b/Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEHold.uasset new file mode 100644 index 0000000..99c00db --- /dev/null +++ b/Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEHold.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:822cd9f7904f60ae7660b7e6955cc79094d4313591f44089fc746356d6d5ac77 +size 61073 diff --git a/Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEMulti.uasset b/Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEMulti.uasset new file mode 100644 index 0000000..f38dec6 --- /dev/null +++ b/Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEMulti.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a57408effd911a48809e2423c06f6e23425b2af9f5fa0746dd365c5aeade55b +size 61238 diff --git a/Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTESingle.uasset b/Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTESingle.uasset new file mode 100644 index 0000000..1a5ffe4 --- /dev/null +++ b/Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTESingle.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:558c84fe46db65f5ab76797c6b5d649a52e30b5cdc114018c32738696abe00b6 +size 59913 diff --git a/Content/Levels/Test/L_Test.umap b/Content/Levels/Test/L_Test.umap index c102713..c573f40 100644 --- a/Content/Levels/Test/L_Test.umap +++ b/Content/Levels/Test/L_Test.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94e0ccda50b0109428a8364a0e201c8853ceda986185538fe2b3a44070717b99 -size 2080437 +oid sha256:2e4b551c8a5619b92644fb1ef11c2b8302b7400e4cb1c53a4beb539e633239d4 +size 2094425 diff --git a/Content/Levels/Test/Sequences/Seq_TestCutscene.uasset b/Content/Levels/Test/Sequences/Seq_TestCutscene.uasset index fa3a3361c88049abb3ba41db15e7107ebbda0448..b4fb5fa99f869a71c078cdfbcb337a9e3592b7bc 100644 GIT binary patch literal 129 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 NrbYU literal 13533 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 UC7&dw%iLS!(pf$JM;fI6KOM*@`Tzg` diff --git a/Content/Misc/ImportTest/M_ImportTest_BarrelRings.uasset b/Content/Misc/ImportTest/M_ImportTest_BarrelRings.uasset index 46914cac214a43b8d596cfc39d860230e03fb283..bdda9ad0c2a6edf626713c1dce772e02cf9e3e7a 100644 GIT binary patch literal 130 zcmWN?OA^8$3;@tQr{Dq>Lc^!M4S__MQRztS!qe;9yo=wnkC$%edCc9Idp~avnalt7 zp{0zcnFkkhff~K)*|PItrxji0K+cL-&n0gVeIkeGFb7B(1qg(=g7Yk~SWBS_#+23? NqgAtiS%cj$sUPx$CyM|8 literal 10948 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 UAb>(+@0odtw>9Yq421mu2SPApga7~l diff --git a/Content/Misc/ImportTest/SM_ImportTest_Barrel.uasset b/Content/Misc/ImportTest/SM_ImportTest_Barrel.uasset index 56a16325350272585eeec28defd08d7192e2e30a..77ff968bd571aefcec67ca0975475489523e5467 100644 GIT binary patch literal 130 zcmWN?NfN>!5CFhCuiyiQEyI%E3=_vx#(h{fRL=O;1aYz+T&iSwY^j-mYT`2IE`M% N1cJx6N=Q0r@dNxkC;R{a literal 59070 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 - if(auto level = world->GetCurrentLevel()) - if(auto script = level->GetLevelScriptActor()) - return Cast(script); + if(obj) + if(auto world = obj->GetWorld()) + if(auto level = world->GetCurrentLevel()) + if(auto script = level->GetLevelScriptActor()) + return Cast(script); return nullptr; } APlayerBase* UCommonFunctions::GetPlayer(UObject* obj) { - if(auto pc = UGameplayStatics::GetPlayerController(obj->GetWorld(), 0)) - if(auto pawn = pc->GetPawn()) - return Cast(pawn); + if(obj) + if(auto pc = UGameplayStatics::GetPlayerController(obj->GetWorld(), 0)) + if(auto pawn = pc->GetPawn()) + return Cast(pawn); return nullptr; } + + + +namespace SlowMotion +{ + FTimerHandle timer; + float targetDilation; + FWorldDilationChangedDelegate worldDilationChangedDelegate; +} + +void UCommonFunctions::EnterSlowMotion(float duration) +{ + if(SlowMotion::targetDilation == SlowMotion::slowDilation) + return; + + SlowMotion::targetDilation = SlowMotion::slowDilation; + + auto GI = UCustomGameInstanceBase::GetGameInstance(); + if(!GI) + return; + + auto world = GI->GetWorld(); + world->GetTimerManager().SetTimer(SlowMotion::timer, []() { SlowMotionTick(); }, 0.01f, true); // wrapped in lambda due to some template function class referencing +} + +void UCommonFunctions::ExitSlowMotion(float duration) +{ + if(SlowMotion::targetDilation == SlowMotion::normalDilation) + return; + + SlowMotion::targetDilation = SlowMotion::normalDilation; + + auto GI = UCustomGameInstanceBase::GetGameInstance(); + if(!GI) + return; + + auto world = GI->GetWorld(); + world->GetTimerManager().SetTimer(SlowMotion::timer, []() { SlowMotionTick(); }, 0.01f, true); +} + +FWorldDilationChangedDelegate& UCommonFunctions::GetWorldDilationChangedDelegate() +{ + return SlowMotion::worldDilationChangedDelegate; +} + +void UCommonFunctions::SlowMotionTick() +{ + const UWorld* world = UCustomGameInstanceBase::GetGameInstance()->GetWorld(); + const float currentDilation = UGameplayStatics::GetGlobalTimeDilation(world); + float newDilation = FMath::FInterpTo(currentDilation, SlowMotion::targetDilation, 1, SlowMotion::interpolationSpeed); + + UGameplayStatics::SetGlobalTimeDilation(world, newDilation); + SlowMotion::worldDilationChangedDelegate.Broadcast(newDilation); + if(FMath::IsNearlyEqual(newDilation, SlowMotion::targetDilation, UE_KINDA_SMALL_NUMBER)) + { + UGameplayStatics::SetGlobalTimeDilation(world, SlowMotion::targetDilation); + world->GetTimerManager().ClearTimer(SlowMotion::timer); + } +} diff --git a/Source/Lost_Edge/Private/CommonFunctions.h b/Source/Lost_Edge/Private/CommonFunctions.h index bfb0136..40c5160 100644 --- a/Source/Lost_Edge/Private/CommonFunctions.h +++ b/Source/Lost_Edge/Private/CommonFunctions.h @@ -6,6 +6,8 @@ #include "CommonFunctions.generated.h" +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FWorldDilationChangedDelegate, float, newDilation); + UCLASS() class UCommonFunctions : public UBlueprintFunctionLibrary { @@ -26,4 +28,23 @@ public: UFUNCTION(BlueprintCallable, Category = Player) static class APlayerBase* GetPlayer(class UObject* obj); + + UFUNCTION(BlueprintCallable, Category = World) + static void EnterSlowMotion(float duration = 1.0f); + + UFUNCTION(BlueprintCallable, Category = World) + static void ExitSlowMotion(float duration = 1.0f); + + static FWorldDilationChangedDelegate& GetWorldDilationChangedDelegate(); + +private: + static void SlowMotionTick(); + }; + +namespace SlowMotion +{ + constexpr float normalDilation = 1.0f; + constexpr float slowDilation = 0.2f; + constexpr float interpolationSpeed = 0.1f; +} diff --git a/Source/Lost_Edge/Private/Levels/Level3.cpp b/Source/Lost_Edge/Private/Levels/Level3.cpp index de192b4..b80c2f3 100644 --- a/Source/Lost_Edge/Private/Levels/Level3.cpp +++ b/Source/Lost_Edge/Private/Levels/Level3.cpp @@ -14,8 +14,6 @@ void ALevel3::BeginPlay() { - AMainGameModeBase::leadLevel = this; - ALevelBase::BeginPlay(); CallNextState(); diff --git a/Source/Lost_Edge/Private/Levels/Level4.cpp b/Source/Lost_Edge/Private/Levels/Level4.cpp index 23192d8..b9f2b62 100644 --- a/Source/Lost_Edge/Private/Levels/Level4.cpp +++ b/Source/Lost_Edge/Private/Levels/Level4.cpp @@ -14,8 +14,6 @@ void ALevel4::BeginPlay() { - AMainGameModeBase::leadLevel = this; - ALevelBase::BeginPlay(); CallNextState(); diff --git a/Source/Lost_Edge/Private/Levels/Level5.cpp b/Source/Lost_Edge/Private/Levels/Level5.cpp index cf03d92..cfe7740 100644 --- a/Source/Lost_Edge/Private/Levels/Level5.cpp +++ b/Source/Lost_Edge/Private/Levels/Level5.cpp @@ -14,8 +14,6 @@ void ALevel5::BeginPlay() { - AMainGameModeBase::leadLevel = this; - ALevelBase::BeginPlay(); CallNextState(); diff --git a/Source/Lost_Edge/Private/Levels/LevelBase.cpp b/Source/Lost_Edge/Private/Levels/LevelBase.cpp index abad90f..10acc8f 100644 --- a/Source/Lost_Edge/Private/Levels/LevelBase.cpp +++ b/Source/Lost_Edge/Private/Levels/LevelBase.cpp @@ -18,7 +18,7 @@ void ALevelBase::BeginPlay() { - AMainGameModeBase::leadLevel = this; + AMainGameModeBase::leadLevel = TStrongObjectPtr{ this }; if(auto world = GetWorld()) { diff --git a/Source/Lost_Edge/Private/MainGameModeBase.cpp b/Source/Lost_Edge/Private/MainGameModeBase.cpp index 86138ba..1e8056c 100644 --- a/Source/Lost_Edge/Private/MainGameModeBase.cpp +++ b/Source/Lost_Edge/Private/MainGameModeBase.cpp @@ -13,20 +13,23 @@ #include "DialogueManager.h" #include "Levels/LevelBase.h" #include "QuestManager.h" +#include "QuickTimeEvent.h" #include "Widgets/WidgetsManager.h" -UWidgetsManager* AMainGameModeBase::_widgetsManager = nullptr; -UCutsceneManager* AMainGameModeBase::_cutsceneManager = nullptr; -UDialogueManager* AMainGameModeBase::_dialogueManager = nullptr; -UQuestManager* AMainGameModeBase::_questManager = nullptr; -ALevelBase* AMainGameModeBase::leadLevel = nullptr; +TStrongObjectPtr AMainGameModeBase::_widgetsManager = nullptr; +TStrongObjectPtr AMainGameModeBase::_cutsceneManager = nullptr; +TStrongObjectPtr AMainGameModeBase::_quickTimeEventManager = nullptr; +TStrongObjectPtr AMainGameModeBase::_dialogueManager = nullptr; +TStrongObjectPtr AMainGameModeBase::_questManager = nullptr; +TStrongObjectPtr AMainGameModeBase::leadLevel = nullptr; void AMainGameModeBase::StartPlay() { - _widgetsManager = NewObject(this, widgetManagerClass); - _cutsceneManager = NewObject(this); - _dialogueManager = NewObject(this); - _questManager = NewObject(this); + _widgetsManager = TStrongObjectPtr{ NewObject(this, widgetManagerClass) }; + _cutsceneManager = TStrongObjectPtr{ NewObject(this) }; + _quickTimeEventManager = TStrongObjectPtr{ NewObject(this) }; + _dialogueManager = TStrongObjectPtr{ NewObject(this) }; + _questManager = TStrongObjectPtr{ NewObject(this) }; AGameModeBase::StartPlay(); @@ -58,16 +61,21 @@ bool AMainGameModeBase::SetPause(APlayerController* PC, FCanUnpause CanUnpauseDe UWidgetsManager* AMainGameModeBase::GetWidgetsManager() { - return _widgetsManager; + return _widgetsManager.Get(); } UCutsceneManager* AMainGameModeBase::GetCutsceneManager() { - return _cutsceneManager; + return _cutsceneManager.Get(); +} + +UQuickTimeEventManager* AMainGameModeBase::GetQuickTimeEventManager() +{ + return _quickTimeEventManager.Get(); } UDialogueManager* AMainGameModeBase::GetDialogueManager() { - return _dialogueManager; + return _dialogueManager.Get(); } void AMainGameModeBase::CallNextLevelState() diff --git a/Source/Lost_Edge/Private/MainGameModeBase.h b/Source/Lost_Edge/Private/MainGameModeBase.h index 503e960..80d0661 100644 --- a/Source/Lost_Edge/Private/MainGameModeBase.h +++ b/Source/Lost_Edge/Private/MainGameModeBase.h @@ -23,6 +23,8 @@ public: UFUNCTION(BlueprintPure) static class UCutsceneManager* GetCutsceneManager(); UFUNCTION(BlueprintPure) + static class UQuickTimeEventManager* GetQuickTimeEventManager(); + UFUNCTION(BlueprintPure) static class UDialogueManager* GetDialogueManager(); UFUNCTION(BlueprintCallable) @@ -32,7 +34,7 @@ public: void SwitchCameraMode(); - static class ALevelBase* leadLevel; + static TStrongObjectPtr leadLevel; FQuestsUpdateDelegate questsUpdateDelegate; @@ -41,8 +43,9 @@ protected: TSubclassOf widgetManagerClass; private: - static class UWidgetsManager* _widgetsManager; - static class UCutsceneManager* _cutsceneManager; - static class UDialogueManager* _dialogueManager; - static class UQuestManager* _questManager; + static TStrongObjectPtr _widgetsManager; + static TStrongObjectPtr _cutsceneManager; + static TStrongObjectPtr _quickTimeEventManager; + static TStrongObjectPtr _dialogueManager; + static TStrongObjectPtr _questManager; }; diff --git a/Source/Lost_Edge/Private/PlayerBase.cpp b/Source/Lost_Edge/Private/PlayerBase.cpp index 79780ed..07dda52 100644 --- a/Source/Lost_Edge/Private/PlayerBase.cpp +++ b/Source/Lost_Edge/Private/PlayerBase.cpp @@ -12,6 +12,7 @@ #include "Kismet/GameplayStatics.h" #include "Kismet/KismetMathLibrary.h" + #include "CustomGameInstanceBase.h" #include "CustomGameUserSettings.h" #include "Interactable/Activators/InteractableActivator.h" @@ -87,8 +88,6 @@ void APlayerBase::BeginPlay() playerController = Cast(GetController()); if(playerController) { - inputComponent = Cast(playerController->InputComponent);; - if(auto inputSubsystem = ULocalPlayer::GetSubsystem(playerController->GetLocalPlayer())) { if(auto GI = Cast(GetWorld()->GetGameInstance())) @@ -100,11 +99,30 @@ void APlayerBase::BeginPlay() } } } + + inputComponent = Cast(playerController->InputComponent); + if(inputComponent) + { + ((UInputComponent*)inputComponent)->BindAction(TEXT("AnyKey"), IE_Pressed, this, &APlayerBase::OnAnyKeyPressed); + ((UInputComponent*)inputComponent)->BindAction(TEXT("AnyKey"), IE_Released, this, &APlayerBase::OnAnyKeyReleased); + } } LoadInteractablesActivators(); } +void APlayerBase::OnAnyKeyPressed(FKey key) +{ + if(onAnyKeyPressedDelegate.IsBound()) + onAnyKeyPressedDelegate.Broadcast(key); +} + +void APlayerBase::OnAnyKeyReleased(FKey key) +{ + if(onAnyKeyReleasedDelegate.IsBound()) + onAnyKeyReleasedDelegate.Broadcast(key); +} + bool APlayerBase::IsMoving() { return bIsMoving; diff --git a/Source/Lost_Edge/Private/PlayerBase.h b/Source/Lost_Edge/Private/PlayerBase.h index 69d7028..8c3590c 100644 --- a/Source/Lost_Edge/Private/PlayerBase.h +++ b/Source/Lost_Edge/Private/PlayerBase.h @@ -8,6 +8,8 @@ enum class EActivatorType : uint8; +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPlayerAnyKeyPressedDelegate, FKey, key); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPlayerAnyKeyReleasedDelegate, FKey, key); DECLARE_DYNAMIC_MULTICAST_DELEGATE(FPlayerMovedDelegate); USTRUCT(BlueprintType) @@ -63,6 +65,9 @@ public: FPlayerMovedDelegate OnPlayerMoved; FVector moveVector; + FPlayerAnyKeyPressedDelegate onAnyKeyPressedDelegate; + FPlayerAnyKeyReleasedDelegate onAnyKeyReleasedDelegate; + class UEnhancedInputComponent* inputComponent = nullptr; class AActor* leftPocketItem = nullptr; @@ -71,6 +76,9 @@ public: protected: virtual void BeginPlay() override; + void OnAnyKeyPressed(FKey key); + void OnAnyKeyReleased(FKey key); + UFUNCTION(BlueprintCallable, Category = CameraMode) void SwitchToCameraPawn(); diff --git a/Source/Lost_Edge/Private/QuickTimeEvent.cpp b/Source/Lost_Edge/Private/QuickTimeEvent.cpp new file mode 100644 index 0000000..333f9d3 --- /dev/null +++ b/Source/Lost_Edge/Private/QuickTimeEvent.cpp @@ -0,0 +1,182 @@ +// Oleg Petruny proprietary. + + +#include "QuickTimeEvent.h" + +#include "Kismet/GameplayStatics.h" + +#include "CommonFunctions.h" +#include "MainGameModeBase.h" +#include "PlayerBase.h" +#include "Widgets/WidgetsManager.h" + +int32 Event::counter = 0; + +Event::Event() +{ + _id = counter++; +} + +Event::Event(EQuickTimeEventType type, FKey& key, FQuickTimeEventEndCallback& callback, bool sequence) + : Event() +{ + this->type = type; + this->key = key; + this->callback = callback; + this->sequence = sequence; +} + +inline int32 Event::GetId() +{ + return _id; +} + +void UQuickTimeEventManager::ShowQuickTimeEvent(FQuickTimeEventEnqueProperties properties) +{ + UE_LOG(LogTemp, Log, TEXT("ShowQuickTimeEvent Start")); + OnFirstEventInit(); + FScopeLock lock1(&_lock); + CreateEvent(properties, false); + UE_LOG(LogTemp, Log, TEXT("ShowQuickTimeEvent End")); +} + +void UQuickTimeEventManager::EnqueQuickTimeEvent(FQuickTimeEventEnqueProperties properties) +{ + UE_LOG(LogTemp, Log, TEXT("EnqueQuickTimeEvent Start")); + OnFirstEventInit(); + { + FScopeLock lock1(&_lock); + _nextEvents.Enqueue(properties); + } + ShowNextEvent(); + UE_LOG(LogTemp, Log, TEXT("EnqueQuickTimeEvent End")); +} + +void UQuickTimeEventManager::ShowNextEvent() +{ + UE_LOG(LogTemp, Log, TEXT("ShowNextEvent Start")); + FScopeLock lock1(&_lock); + FQuickTimeEventEnqueProperties properties; + _nextEvents.Dequeue(properties); + CreateEvent(properties, true); + UE_LOG(LogTemp, Log, TEXT("ShowNextEvent End")); +} + +void UQuickTimeEventManager::OnEventEnd(int32 id, EQuickTimeEventResult result) +{ + UE_LOG(LogTemp, Log, TEXT("OnEventEnd Start")); + FScopeLock lock1(&_lock); + Event event; + if(!_events.RemoveAndCopyValue(id, event)) + return; + + GetWorld()->GetTimerManager().ClearTimer(event.timer); + + if(event.callback.IsBound()) + event.callback.Execute(result); + + if(event.sequence && !_nextEvents.IsEmpty()) + { + ShowNextEvent(); + UE_LOG(LogTemp, Log, TEXT("OnEventEnd End")); + return; + } + + if(_events.IsEmpty()) + { + if(auto player = UCommonFunctions::GetPlayer(this)) + { + player->onAnyKeyPressedDelegate.RemoveDynamic(this, &UQuickTimeEventManager::OnInputPressed); + player->onAnyKeyReleasedDelegate.RemoveDynamic(this, &UQuickTimeEventManager::OnInputReleased); + } + UCommonFunctions::ExitSlowMotion(); + } + UE_LOG(LogTemp, Log, TEXT("OnEventEnd End")); +} + +void UQuickTimeEventManager::OnInput(const FKey& key, bool released) +{ + for(auto eventMapping : _events) + { + if(eventMapping.Value.key == key) + { + EQuickTimeEventResult result = EQuickTimeEventResult::Success; + + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + { + result = WM->ProcessQuickTimeEvent(eventMapping.Key, released); + + switch(result) + { + case EQuickTimeEventResult::FailedKey: // its not a failed key, but special state to do nothing (eg. holding event) + return; + default: + // the result is success or failed time and widget is self removed + break; + } + } + + OnEventEnd(eventMapping.Key, result); + return; + } + } + + if(released) + return; + + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + { + while(_events.Num() > 0) + { + WM->RemoveQuickTimeEvent(_events.begin()->Key); + OnEventEnd(_events.begin()->Key, EQuickTimeEventResult::FailedKey); + } + } + else + { + while(_events.Num() > 0) + OnEventEnd(_events.begin()->Key, EQuickTimeEventResult::FailedKey); + } +} + +void UQuickTimeEventManager::OnInputPressed(FKey key) +{ + OnInput(key, false); +} + +void UQuickTimeEventManager::OnInputReleased(FKey key) +{ + OnInput(key, true); +} + +void UQuickTimeEventManager::OnFirstEventInit() +{ + if(_events.IsEmpty()) + { + if(auto player = UCommonFunctions::GetPlayer(this)) + { + GetWorld()->GetTimerManager().SetTimerForNextTick([manager = this, player = player]() + { + player->onAnyKeyPressedDelegate.AddDynamic(manager, &UQuickTimeEventManager::OnInputPressed); + player->onAnyKeyReleasedDelegate.AddDynamic(manager, &UQuickTimeEventManager::OnInputReleased); + }); + } + UCommonFunctions::EnterSlowMotion(); + } +} + +void UQuickTimeEventManager::CreateEvent(FQuickTimeEventEnqueProperties& properties, bool sequence) +{ + Event event{ properties.type, properties.key, properties.callback, sequence }; + GetWorld()->GetTimerManager().SetTimer(event.timer, [id = event.GetId(), manager = this]() + { + EQuickTimeEventResult result = EQuickTimeEventResult::FailedTime; + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + result = WM->RemoveQuickTimeEvent(id); + manager->OnEventEnd(id, result); + }, properties.duration, false); + _events.Add(event.GetId(), event); + + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + WM->ShowQuickTimeEvent(event.GetId(), properties); +} diff --git a/Source/Lost_Edge/Private/QuickTimeEvent.h b/Source/Lost_Edge/Private/QuickTimeEvent.h new file mode 100644 index 0000000..bdc0006 --- /dev/null +++ b/Source/Lost_Edge/Private/QuickTimeEvent.h @@ -0,0 +1,95 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "UObject/Object.h" + +#include "QuickTimeEvent.generated.h" + +UENUM(BlueprintType) +enum class EQuickTimeEventType : uint8 +{ + SinglePress, + MultiPress, + Hold +}; + +UENUM(BlueprintType) +enum class EQuickTimeEventResult : uint8 +{ + Success, + FailedTime, + FailedKey +}; + +DECLARE_DYNAMIC_DELEGATE_OneParam(FQuickTimeEventEndCallback, EQuickTimeEventResult, result); + +USTRUCT(BlueprintType) +struct FQuickTimeEventEnqueProperties +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + EQuickTimeEventType type = EQuickTimeEventType::SinglePress; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FKey key = EKeys::F; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float duration = 1.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FVector2D anchor = FVector2D::Unit45Deg; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FQuickTimeEventEndCallback callback; +}; + +struct Event +{ +public: + Event(); + Event(EQuickTimeEventType type, FKey& key, FQuickTimeEventEndCallback& callback, bool sequence); + + inline int32 GetId(); + + EQuickTimeEventType type; + FKey key; + FTimerHandle timer; + FQuickTimeEventEndCallback callback; + bool sequence; + +private: + int32 _id; + static int32 counter; +}; + +UCLASS(Blueprintable, BlueprintType) +class UQuickTimeEventManager : public UObject +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable) + void ShowQuickTimeEvent(FQuickTimeEventEnqueProperties properties); + + UFUNCTION(BlueprintCallable) + void EnqueQuickTimeEvent(FQuickTimeEventEnqueProperties properties); + +protected: + void ShowNextEvent(); + void OnEventEnd(int32 id, EQuickTimeEventResult result); + + void OnInput(const FKey& key, bool released); + UFUNCTION() + void OnInputPressed(FKey key); + UFUNCTION() + void OnInputReleased(FKey key); + + void OnFirstEventInit(); + void CreateEvent(FQuickTimeEventEnqueProperties& properties, bool sequence); + + TQueue _nextEvents; + TMap _events; + FCriticalSection _lock; +}; diff --git a/Source/Lost_Edge/Private/Widgets/AdvanceButton.cpp b/Source/Lost_Edge/Private/Widgets/AdvanceButton.cpp deleted file mode 100644 index 564c4d0..0000000 --- a/Source/Lost_Edge/Private/Widgets/AdvanceButton.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Oleg Petruny proprietary. - - -#include "AdvanceButton.h" - -#include "Components/ButtonSlot.h" - -//FReply SAdvanceButton::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) -//{ -// if(!hitboxTexture) -// return SButton::OnMouseMove(MyGeometry, MouseEvent); -// -// FVector2D locPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()); -// locPos /= MyGeometry.GetLocalSize(); -// int width = hitboxTexture->GetPlatformData()->SizeX; -// locPos.X *= width; -// locPos.Y *= hitboxTexture->GetPlatformData()->SizeY; -// long pixelIndex = (locPos.Y * width) + locPos.X; -// -// FColor* imageData = static_cast((hitboxTexture->GetPlatformData()->Mips[0]).BulkData.Lock(LOCK_READ_ONLY)); -// bool hovered = imageData && imageData[pixelIndex].A <= hitboxTextureAlphaThreshold; -// hitboxTexture->GetPlatformData()->Mips[0].BulkData.Unlock(); -// -// if(hovered != bIsHovered) -// { -// bIsHovered = hovered; -// if(bIsHovered) -// SButton::OnMouseEnter(MyGeometry, MouseEvent); -// else -// SButton::OnMouseLeave(MouseEvent); -// } -// -// return SButton::OnMouseMove(MyGeometry, MouseEvent); -//} -// -//void UAdvanceButton::SynchronizeProperties() -//{ -// Super::SynchronizeProperties(); -// (static_cast(MyButton.Get()))->hitboxTexture = hitboxTexture; -// (static_cast(MyButton.Get()))->hitboxTextureAlphaThreshold = hitboxTextureAlphaThreshold; -//} -// -//TSharedRef UAdvanceButton::RebuildWidget() -//{ -// TSharedPtr advanceButton = SNew(SAdvanceButton) -// .OnClicked(BIND_UOBJECT_DELEGATE(FOnClicked, SlateHandleClicked)) -// .OnPressed(BIND_UOBJECT_DELEGATE(FSimpleDelegate, SlateHandlePressed)) -// .OnReleased(BIND_UOBJECT_DELEGATE(FSimpleDelegate, SlateHandleReleased)) -// .OnHovered_UObject(this, &ThisClass::SlateHandleHovered) -// .OnUnhovered_UObject(this, &ThisClass::SlateHandleUnhovered) -// .ButtonStyle(&WidgetStyle) -// .ClickMethod(ClickMethod) -// .TouchMethod(TouchMethod) -// .IsFocusable(IsFocusable); -// -// advanceButton->hitboxTexture = hitboxTexture; -// advanceButton->hitboxTextureAlphaThreshold = hitboxTextureAlphaThreshold; -// MyButton = advanceButton; -// -// if(GetChildrenCount() > 0) -// Cast(GetContentSlot())->BuildSlot(MyButton.ToSharedRef()); -// -// return MyButton.ToSharedRef(); -//} \ No newline at end of file diff --git a/Source/Lost_Edge/Private/Widgets/AdvanceButton.h b/Source/Lost_Edge/Private/Widgets/AdvanceButton.h deleted file mode 100644 index d2d8a5b..0000000 --- a/Source/Lost_Edge/Private/Widgets/AdvanceButton.h +++ /dev/null @@ -1,51 +0,0 @@ -// Oleg Petruny proprietary. - -#pragma once - -#include "Components/Button.h" - -#include "AdvanceButton.generated.h" - -class SAdvanceButton : public SButton -{ -public: - //virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override - //{ - // if(!bIsHovered) return FReply::Unhandled(); - // return SButton::OnMouseButtonDown(MyGeometry, MouseEvent); - //} - //virtual FReply OnMouseButtonDoubleClick(const FGeometry& InMyGeometry, const FPointerEvent& InMouseEvent) override - //{ - // if(!bIsHovered) return FReply::Unhandled(); - // return SButton::OnMouseButtonDoubleClick(InMyGeometry, InMouseEvent); - //} - //virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; - //virtual void OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override - //{ - // if(hitboxTexture) return; - // return SButton::OnMouseEnter(MyGeometry, MouseEvent); - //} - //virtual TSharedPtr GetToolTip() override - //{ - // return (bIsHovered ? SWidget::GetToolTip() : nullptr); - //} - // - //UTexture2D* hitboxTexture = nullptr; - //uint8 hitboxTextureAlphaThreshold = 0; -}; - -UCLASS() -class UAdvanceButton : public UButton -{ - GENERATED_BODY() - // - //public: - // virtual void SynchronizeProperties() override; - // virtual TSharedRef RebuildWidget() override; - // - // UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "AdvanceButton") - // UTexture2D* hitboxTexture = nullptr; - // - // UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "AdvanceButton", meta = (ClampMin = "0.0", ClampMax = "255.0", UIMin = "0.0", UIMax = "255.0")) - // int hitboxTextureAlphaThreshold = 0; -}; diff --git a/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.cpp b/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.cpp new file mode 100644 index 0000000..b34b551 --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.cpp @@ -0,0 +1,58 @@ +// Oleg Petruny proprietary. + + +#include "QuickTimeEventWidget.h" + +#include "Animation/WidgetAnimation.h" + +#include "QuickTimeEvent.h" +#include "QuickTimeEventWidgetManager.h" + +void UQuickTimeEventWidget::NativeConstruct() +{ + FWidgetAnimationDynamicEvent onTimerFinish; + onTimerFinish.BindDynamic(this, &UQuickTimeEventWidget::RemoveEvent); + BindToAnimationFinished(eventAnimation, onTimerFinish); + + FWidgetAnimationDynamicEvent onRemove; + onRemove.BindDynamic(this, &UQuickTimeEventWidget::RemoveFromManager); + BindToAnimationFinished(removeAnimation, onRemove); + + return Super::NativeConstruct(); +} + +void UQuickTimeEventWidget::Show() +{ + SetVisibility(ESlateVisibility::Visible); + const float playbackSpeed = eventAnimation->GetEndTime() / duration; + + PlayAnimation(eventAnimation, 0, 1, EUMGSequencePlayMode::Forward, playbackSpeed, false); +} + +void UQuickTimeEventWidget::RemoveFromManager() +{ + manager->RemoveEvent(id); +} + +EQuickTimeEventResult UQuickTimeEventWidget::_Process(const bool released) +{ + Process(released); + + return result; +} + +EQuickTimeEventResult UQuickTimeEventWidget::_ProcessBeforeRemoving() +{ + ProcessBeforeRemoving(); + + return result; +} + +void UQuickTimeEventWidget::RemoveEvent() +{ + if(removing) + return; + + removing = true; + PlayAnimation(removeAnimation, 0, 1, EUMGSequencePlayMode::Forward, 1, false); +} diff --git a/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.h b/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.h new file mode 100644 index 0000000..6a07915 --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.h @@ -0,0 +1,54 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "Widgets/ResolutionResponsiveUserWidget.h" + +#include "QuickTimeEventWidget.generated.h" + +enum class EQuickTimeEventResult : uint8; + +UCLASS(Blueprintable, Abstract) +class UQuickTimeEventWidget : public UResolutionResponsiveUserWidget +{ + GENERATED_BODY() + +public: + void Show(); + + UFUNCTION(BlueprintCallable) + void RemoveEvent(); + + UFUNCTION(BlueprintImplementableEvent, BlueprintCallable) + void Process(const bool released); + EQuickTimeEventResult _Process(const bool released); + + UFUNCTION(BlueprintImplementableEvent, BlueprintCallable) + void ProcessBeforeRemoving(); + EQuickTimeEventResult _ProcessBeforeRemoving(); + + + UPROPERTY(meta = (BindWidget)) + class UTextBlock* keyText; + + int32 id; + class UQuickTimeEventWidgetManager* manager; + float duration; + +protected: + virtual void NativeConstruct() override; + + UFUNCTION() + void RemoveFromManager(); + + UPROPERTY(Transient, meta = (BindWidgetAnim)) + class UWidgetAnimation* eventAnimation; + + UPROPERTY(Transient, meta = (BindWidgetAnim)) + class UWidgetAnimation* removeAnimation; + + UPROPERTY(BlueprintReadWrite) + EQuickTimeEventResult result = EQuickTimeEventResult::FailedKey; // special state to do nothing; + + bool removing = false; +}; diff --git a/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidgetManager.cpp b/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidgetManager.cpp new file mode 100644 index 0000000..9316c7a --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidgetManager.cpp @@ -0,0 +1,77 @@ +// Oleg Petruny proprietary. + + +#include "QuickTimeEventWidgetManager.h" + +#include "Animation/UMGSequencePlayer.h" +#include "Animation/WidgetAnimation.h" +#include "Blueprint/WidgetTree.h" +#include "Components/CanvasPanel.h" +#include "Components/CanvasPanelSlot.h" +#include "Components/TextBlock.h" + +#include "CommonFunctions.h" +#include "QuickTimeEvent.h" +#include "Widgets/QuickTimeEventWidget.h" + +void UQuickTimeEventWidgetManager::ShowEvent(const int32 id, const struct FQuickTimeEventEnqueProperties& properties) +{ + FScopeLock Lock(&mappingLock); + + if(eventsMap.Contains(id) || !eventWidgetClasses.Contains(properties.type)) + return; + + auto eventWidget = WidgetTree->ConstructWidget(eventWidgetClasses[properties.type]); + eventWidget->SetVisibility(ESlateVisibility::Hidden); + eventWidget->keyText->SetText(UCommonFunctions::GetKeyDisplayName(properties.key)); + eventWidget->id = id; + eventWidget->manager = this; + eventWidget->duration = properties.duration; + ((UCanvasPanelSlot*)canvas->AddChild(eventWidget))->SetAnchors({ (float)properties.anchor.X, (float)properties.anchor.Y }); + eventWidget->Show(); + + eventsMap.Add(id, eventWidget); +} + +EQuickTimeEventResult UQuickTimeEventWidgetManager::RemoveEvent(const int32 id) +{ + FScopeLock Lock(&mappingLock); + + if(!eventsMap.Contains(id)) + return EQuickTimeEventResult::FailedTime; + + UQuickTimeEventWidget* eventWidget; + eventsMap.RemoveAndCopyValue(id, eventWidget); + auto result = eventWidget->_ProcessBeforeRemoving(); + eventWidget->RemoveEvent(); + return result; +} + +EQuickTimeEventResult UQuickTimeEventWidgetManager::AnimateEvent(const int32 id, const bool released) +{ + FScopeLock Lock(&mappingLock); + + if(!eventsMap.Contains(id)) + return EQuickTimeEventResult::FailedTime; + + return eventsMap[id]->_Process(released); +} + +void UQuickTimeEventWidgetManager::UpdateAnimation(UWidget* widget, float newSpeed) +{ + if(auto eventWidget = Cast(widget)) + { + for(auto player : eventWidget->ActiveSequencePlayers) + { + if(player->GetAnimation()->GetDisplayLabel() != TEXT("eventAnimation")) + continue; + + newSpeed *= player->GetAnimation()->GetEndTime() / eventWidget->duration; + player->SetPlaybackSpeed(newSpeed); + } + + return; + } + + Super::UpdateAnimation(widget, newSpeed); +} diff --git a/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidgetManager.h b/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidgetManager.h new file mode 100644 index 0000000..ded4f4a --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/QuickTimeEventWidgetManager.h @@ -0,0 +1,37 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "Widgets/WorldDilationResponsiveUserWidget.h" + +#include "QuickTimeEventWidgetManager.generated.h" + +enum class EInputAnimatedWidgetAnimation : uint8; +enum class EQuickTimeEventType : uint8; +enum class EQuickTimeEventResult : uint8; +class UQuickTimeEventWidget; + +UCLASS(Blueprintable, Abstract) +class UQuickTimeEventWidgetManager : public UWorldDilationResponsiveUserWidget +{ + GENERATED_BODY() + + friend UQuickTimeEventWidget; + +public: + void ShowEvent(const int32 id, const struct FQuickTimeEventEnqueProperties& properties); + EQuickTimeEventResult RemoveEvent(const int32 id); + EQuickTimeEventResult AnimateEvent(const int32 id, const bool released); + +protected: + virtual void UpdateAnimation(UWidget* widget, float newSpeed) override; + + UPROPERTY(EditDefaultsOnly) + TMap> eventWidgetClasses; + + UPROPERTY(meta = (BindWidget)) + class UCanvasPanel* canvas; + + TMap eventsMap; + FCriticalSection mappingLock; +}; diff --git a/Source/Lost_Edge/Private/Widgets/WidgetsManager.cpp b/Source/Lost_Edge/Private/Widgets/WidgetsManager.cpp index 095caaf..53bfa79 100644 --- a/Source/Lost_Edge/Private/Widgets/WidgetsManager.cpp +++ b/Source/Lost_Edge/Private/Widgets/WidgetsManager.cpp @@ -22,6 +22,7 @@ #include "Widgets/InventoryWidget.h" #include "Widgets/JournalWidget.h" #include "Widgets/MainMenu/MainMenuWidget.h" +#include "Widgets/QuickTimeEventWidgetManager.h" void UWidgetsManager::Init() { @@ -52,6 +53,7 @@ void UWidgetsManager::Init() if(auto instance = CreateWidget(PC, interactableHintWidgetManagerClass)) { interactableHintWidgetManager = instance; + interactableHintWidgetManager->SetVisibility(ESlateVisibility::Visible); interactableHintWidgetManager->AddToViewport(); } if(auto instance = CreateWidget(PC, cutsceneSkipWidgetClass)) @@ -60,6 +62,12 @@ void UWidgetsManager::Init() cutsceneSkipWidget->SetVisibility(ESlateVisibility::Hidden); cutsceneSkipWidget->AddToViewport(); } + if(auto instance = CreateWidget(PC, quickTimeEventWidgetManagerClass)) + { + quickTimeEventWidgetManager = instance; + quickTimeEventWidgetManager->SetVisibility(ESlateVisibility::Visible); + quickTimeEventWidgetManager->AddToViewport(); + } if(auto instance = CreateWidget(PC, dialogueRowWidgetManagerClass)) { dialogueRowWidgetManager = instance; @@ -183,6 +191,23 @@ void UWidgetsManager::AnimateCutsceneWidget(const EInputAnimatedWidgetAnimation +void UWidgetsManager::ShowQuickTimeEvent(const int32 id, const struct FQuickTimeEventEnqueProperties& properties) +{ + quickTimeEventWidgetManager->ShowEvent(id, properties); +} + +EQuickTimeEventResult UWidgetsManager::RemoveQuickTimeEvent(const int32 id) +{ + return quickTimeEventWidgetManager->RemoveEvent(id); +} + +EQuickTimeEventResult UWidgetsManager::ProcessQuickTimeEvent(const int32 id, const bool released) +{ + return quickTimeEventWidgetManager->AnimateEvent(id, released); +} + + + void UWidgetsManager::SetInputDialogueWidget(const FKey key, const FText desc, FDialogueSkipDelegate& delegate) { dialogueRowWidgetManager->SetInput(key, desc, delegate); diff --git a/Source/Lost_Edge/Private/Widgets/WidgetsManager.h b/Source/Lost_Edge/Private/Widgets/WidgetsManager.h index e49fb2b..e23034e 100644 --- a/Source/Lost_Edge/Private/Widgets/WidgetsManager.h +++ b/Source/Lost_Edge/Private/Widgets/WidgetsManager.h @@ -7,6 +7,7 @@ #include "WidgetsManager.generated.h" enum class EInputAnimatedWidgetAnimation : uint8; +enum class EQuickTimeEventResult : uint8; UCLASS(Blueprintable) class UWidgetsManager : public UObject @@ -34,6 +35,10 @@ public: void DisableCutsceneWidget(); void AnimateCutsceneWidget(const EInputAnimatedWidgetAnimation animation); + void ShowQuickTimeEvent(const int32 id, const struct FQuickTimeEventEnqueProperties& properties); + EQuickTimeEventResult RemoveQuickTimeEvent(const int32 id); + EQuickTimeEventResult ProcessQuickTimeEvent(const int32 id, const bool released); + void SetInputDialogueWidget(const FKey key, const FText desc, class FDialogueSkipDelegate& delegate); void ShowDialogueWidget(const struct FDialogueRow& dialogue); void HideDialogueWidget(const struct FDialogueRow& dialogue); @@ -68,6 +73,10 @@ protected: TSubclassOf cutsceneSkipWidgetClass; // never hidden class UCutsceneSkipWidget* cutsceneSkipWidget = nullptr; + UPROPERTY(EditDefaultsOnly) + TSubclassOf quickTimeEventWidgetManagerClass; // never hidden + class UQuickTimeEventWidgetManager* quickTimeEventWidgetManager = nullptr; + UPROPERTY(EditDefaultsOnly) TSubclassOf dialogueRowWidgetManagerClass; // hidden in cutscene class UDialogueRowWidgetManager* dialogueRowWidgetManager = nullptr; diff --git a/Source/Lost_Edge/Private/Widgets/WorldDilationResponsiveUserWidget.cpp b/Source/Lost_Edge/Private/Widgets/WorldDilationResponsiveUserWidget.cpp new file mode 100644 index 0000000..1216c89 --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/WorldDilationResponsiveUserWidget.cpp @@ -0,0 +1,81 @@ +// Oleg Petruny proprietary. + + +#include "WorldDilationResponsiveUserWidget.h" + +#include "Animation/UMGSequencePlayer.h" +#include "Animation/WidgetAnimation.h" +#include "Components/PanelWidget.h" + +#include "CommonFunctions.h" + +bool UWorldDilationResponsiveUserWidget::Initialize() +{ + UCommonFunctions::GetWorldDilationChangedDelegate().AddDynamic(this, &UWorldDilationResponsiveUserWidget::UpdateAnimations); + + return UUserWidget::Initialize(); +} + +void UWorldDilationResponsiveUserWidget::BeginDestroy() +{ + UCommonFunctions::GetWorldDilationChangedDelegate().RemoveDynamic(this, &UWorldDilationResponsiveUserWidget::UpdateAnimations); + + UUserWidget::BeginDestroy(); +} + +void UWorldDilationResponsiveUserWidget::UpdateAnimations(float newSpeed) +{ + UpdateAnimation(GetRootWidget(), newSpeed); + + if(auto root = Cast(GetRootWidget())) + { + if(root->GetChildrenCount() == 0) + return; + + // recursion would be simplier... + TArray path{ 0 }; + UWidget* widget = root->GetChildAt(0); + while(widget != root) + { + UpdateAnimation(widget, newSpeed); + + if(path.Num() < maxDepth) + { + if(auto panel = Cast(widget)) + { + if(panel->GetChildrenCount()) + { + path.Add(0); + widget = panel->GetChildAt(0); + continue; + } + } + } + + while(path.Num()) + { + auto panel = widget->GetParent(); + int32& i = path[path.Num() - 1]; + if(++i < panel->GetChildrenCount()) + { + widget = panel->GetChildAt(i); + break; + } + else + { + path.RemoveAt(path.Num() - 1, EAllowShrinking::No); + widget = panel; + } + } + } + } +} + +void UWorldDilationResponsiveUserWidget::UpdateAnimation(UWidget* widget, float newSpeed) +{ + if(auto userWidget = Cast(widget)) + { + for(auto player : userWidget->ActiveSequencePlayers) + player->SetPlaybackSpeed(newSpeed); + } +} diff --git a/Source/Lost_Edge/Private/Widgets/WorldDilationResponsiveUserWidget.h b/Source/Lost_Edge/Private/Widgets/WorldDilationResponsiveUserWidget.h new file mode 100644 index 0000000..243df6e --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/WorldDilationResponsiveUserWidget.h @@ -0,0 +1,25 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "Blueprint/UserWidget.h" + +#include "WorldDilationResponsiveUserWidget.generated.h" + +UCLASS() +class UWorldDilationResponsiveUserWidget : public UUserWidget +{ + GENERATED_BODY() + +public: + virtual bool Initialize() override; + virtual void BeginDestroy() override; + +protected: + UFUNCTION() + void UpdateAnimations(float newSpeed); + virtual void UpdateAnimation(UWidget* widget, float newSpeed); + + UPROPERTY(EditDefaultsOnly) + int32 maxDepth = 2; +};