QTE, crash fixes, bug fixes, optimizations, warnings clearing
This commit is contained in:
parent
1e277a3b5b
commit
a58ef0abcd
@ -5,7 +5,7 @@ GameDefaultMap=/Game/Levels/Test/L_Test.L_Test
|
|||||||
EditorStartupMap=/Game/Levels/Test/L_Test.L_Test
|
EditorStartupMap=/Game/Levels/Test/L_Test.L_Test
|
||||||
bUseSplitscreen=False
|
bUseSplitscreen=False
|
||||||
GlobalDefaultGameMode=/Game/Blueprints/GameModes/BP_MainGameMode.BP_MainGameMode_C
|
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]
|
[/Script/WindowsTargetPlatform.WindowsTargetSettings]
|
||||||
DefaultGraphicsRHI=DefaultGraphicsRHI_DX12
|
DefaultGraphicsRHI=DefaultGraphicsRHI_DX12
|
||||||
|
@ -78,6 +78,7 @@ DefaultViewportMouseCaptureMode=CapturePermanently_IncludingInitialMouseDown
|
|||||||
DefaultViewportMouseLockMode=LockOnCapture
|
DefaultViewportMouseLockMode=LockOnCapture
|
||||||
FOVScale=0.011110
|
FOVScale=0.011110
|
||||||
DoubleClickTime=0.200000
|
DoubleClickTime=0.200000
|
||||||
|
+ActionMappings=(ActionName="AnyKey",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=AnyKey)
|
||||||
DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput
|
DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput
|
||||||
DefaultInputComponentClass=/Script/EnhancedInput.EnhancedInputComponent
|
DefaultInputComponentClass=/Script/EnhancedInput.EnhancedInputComponent
|
||||||
DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks
|
DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks
|
||||||
|
BIN
Content/Blueprints/BP_CustomGameInstance.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Blueprints/BP_CustomGameInstance.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Blueprints/Characters/BP_Player.uasset
(Stored with Git LFS)
BIN
Content/Blueprints/Characters/BP_Player.uasset
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEHold.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEHold.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEMulti.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTEMulti.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTESingle.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Levels/Test/Actors/QuickTimeEventTest/BP_Test_QTESingle.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Levels/Test/L_Test.umap
(Stored with Git LFS)
BIN
Content/Levels/Test/L_Test.umap
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
Content/Levels/Test/Sequences/Seq_Test_Ball.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Levels/Test/Sequences/Seq_Test_Ball.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Levels/Test/Sequences/Seq_Test_Cutscene.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Levels/Test/Sequences/Seq_Test_Cutscene.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/UI/BP_MainWidgetManager.uasset
(Stored with Git LFS)
BIN
Content/UI/BP_MainWidgetManager.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventHold.uasset
(Stored with Git LFS)
Normal file
BIN
Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventHold.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventManager.uasset
(Stored with Git LFS)
Normal file
BIN
Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventManager.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventMultiPress.uasset
(Stored with Git LFS)
Normal file
BIN
Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventMultiPress.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventSinglePress.uasset
(Stored with Git LFS)
Normal file
BIN
Content/UI/Blueprints/QuickTimeEvents/UI_QuickTimeEventSinglePress.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -7,6 +7,7 @@
|
|||||||
#include "Kismet/GameplayStatics.h"
|
#include "Kismet/GameplayStatics.h"
|
||||||
#include "UObject/Object.h"
|
#include "UObject/Object.h"
|
||||||
|
|
||||||
|
#include "CustomGameInstanceBase.h"
|
||||||
#include "Levels/LevelBase.h"
|
#include "Levels/LevelBase.h"
|
||||||
#include "PlayerBase.h"
|
#include "PlayerBase.h"
|
||||||
|
|
||||||
@ -42,17 +43,78 @@ void UCommonFunctions::DestroyActorRecursively(AActor* actor)
|
|||||||
|
|
||||||
ALevelBase* UCommonFunctions::GetCurrentLevelScript(UObject* obj)
|
ALevelBase* UCommonFunctions::GetCurrentLevelScript(UObject* obj)
|
||||||
{
|
{
|
||||||
if(auto world = obj->GetWorld())
|
if(obj)
|
||||||
if(auto level = world->GetCurrentLevel())
|
if(auto world = obj->GetWorld())
|
||||||
if(auto script = level->GetLevelScriptActor())
|
if(auto level = world->GetCurrentLevel())
|
||||||
return Cast<ALevelBase>(script);
|
if(auto script = level->GetLevelScriptActor())
|
||||||
|
return Cast<ALevelBase>(script);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
APlayerBase* UCommonFunctions::GetPlayer(UObject* obj)
|
APlayerBase* UCommonFunctions::GetPlayer(UObject* obj)
|
||||||
{
|
{
|
||||||
if(auto pc = UGameplayStatics::GetPlayerController(obj->GetWorld(), 0))
|
if(obj)
|
||||||
if(auto pawn = pc->GetPawn())
|
if(auto pc = UGameplayStatics::GetPlayerController(obj->GetWorld(), 0))
|
||||||
return Cast<APlayerBase>(pawn);
|
if(auto pawn = pc->GetPawn())
|
||||||
|
return Cast<APlayerBase>(pawn);
|
||||||
return nullptr;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include "CommonFunctions.generated.h"
|
#include "CommonFunctions.generated.h"
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FWorldDilationChangedDelegate, float, newDilation);
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UCommonFunctions : public UBlueprintFunctionLibrary
|
class UCommonFunctions : public UBlueprintFunctionLibrary
|
||||||
{
|
{
|
||||||
@ -26,4 +28,23 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable, Category = Player)
|
UFUNCTION(BlueprintCallable, Category = Player)
|
||||||
static class APlayerBase* GetPlayer(class UObject* obj);
|
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;
|
||||||
|
}
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
void ALevel3::BeginPlay()
|
void ALevel3::BeginPlay()
|
||||||
{
|
{
|
||||||
AMainGameModeBase::leadLevel = this;
|
|
||||||
|
|
||||||
ALevelBase::BeginPlay();
|
ALevelBase::BeginPlay();
|
||||||
|
|
||||||
CallNextState();
|
CallNextState();
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
void ALevel4::BeginPlay()
|
void ALevel4::BeginPlay()
|
||||||
{
|
{
|
||||||
AMainGameModeBase::leadLevel = this;
|
|
||||||
|
|
||||||
ALevelBase::BeginPlay();
|
ALevelBase::BeginPlay();
|
||||||
|
|
||||||
CallNextState();
|
CallNextState();
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
void ALevel5::BeginPlay()
|
void ALevel5::BeginPlay()
|
||||||
{
|
{
|
||||||
AMainGameModeBase::leadLevel = this;
|
|
||||||
|
|
||||||
ALevelBase::BeginPlay();
|
ALevelBase::BeginPlay();
|
||||||
|
|
||||||
CallNextState();
|
CallNextState();
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
void ALevelBase::BeginPlay()
|
void ALevelBase::BeginPlay()
|
||||||
{
|
{
|
||||||
AMainGameModeBase::leadLevel = this;
|
AMainGameModeBase::leadLevel = TStrongObjectPtr<ALevelBase>{ this };
|
||||||
|
|
||||||
if(auto world = GetWorld())
|
if(auto world = GetWorld())
|
||||||
{
|
{
|
||||||
|
@ -13,20 +13,23 @@
|
|||||||
#include "DialogueManager.h"
|
#include "DialogueManager.h"
|
||||||
#include "Levels/LevelBase.h"
|
#include "Levels/LevelBase.h"
|
||||||
#include "QuestManager.h"
|
#include "QuestManager.h"
|
||||||
|
#include "QuickTimeEvent.h"
|
||||||
#include "Widgets/WidgetsManager.h"
|
#include "Widgets/WidgetsManager.h"
|
||||||
|
|
||||||
UWidgetsManager* AMainGameModeBase::_widgetsManager = nullptr;
|
TStrongObjectPtr<UWidgetsManager> AMainGameModeBase::_widgetsManager = nullptr;
|
||||||
UCutsceneManager* AMainGameModeBase::_cutsceneManager = nullptr;
|
TStrongObjectPtr<UCutsceneManager> AMainGameModeBase::_cutsceneManager = nullptr;
|
||||||
UDialogueManager* AMainGameModeBase::_dialogueManager = nullptr;
|
TStrongObjectPtr<UQuickTimeEventManager> AMainGameModeBase::_quickTimeEventManager = nullptr;
|
||||||
UQuestManager* AMainGameModeBase::_questManager = nullptr;
|
TStrongObjectPtr<UDialogueManager> AMainGameModeBase::_dialogueManager = nullptr;
|
||||||
ALevelBase* AMainGameModeBase::leadLevel = nullptr;
|
TStrongObjectPtr<UQuestManager> AMainGameModeBase::_questManager = nullptr;
|
||||||
|
TStrongObjectPtr<ALevelBase> AMainGameModeBase::leadLevel = nullptr;
|
||||||
|
|
||||||
void AMainGameModeBase::StartPlay()
|
void AMainGameModeBase::StartPlay()
|
||||||
{
|
{
|
||||||
_widgetsManager = NewObject<UWidgetsManager>(this, widgetManagerClass);
|
_widgetsManager = TStrongObjectPtr<UWidgetsManager>{ NewObject<UWidgetsManager>(this, widgetManagerClass) };
|
||||||
_cutsceneManager = NewObject<UCutsceneManager>(this);
|
_cutsceneManager = TStrongObjectPtr<UCutsceneManager>{ NewObject<UCutsceneManager>(this) };
|
||||||
_dialogueManager = NewObject<UDialogueManager>(this);
|
_quickTimeEventManager = TStrongObjectPtr<UQuickTimeEventManager>{ NewObject<UQuickTimeEventManager>(this) };
|
||||||
_questManager = NewObject<UQuestManager>(this);
|
_dialogueManager = TStrongObjectPtr<UDialogueManager>{ NewObject<UDialogueManager>(this) };
|
||||||
|
_questManager = TStrongObjectPtr<UQuestManager>{ NewObject<UQuestManager>(this) };
|
||||||
|
|
||||||
AGameModeBase::StartPlay();
|
AGameModeBase::StartPlay();
|
||||||
|
|
||||||
@ -58,16 +61,21 @@ bool AMainGameModeBase::SetPause(APlayerController* PC, FCanUnpause CanUnpauseDe
|
|||||||
|
|
||||||
UWidgetsManager* AMainGameModeBase::GetWidgetsManager()
|
UWidgetsManager* AMainGameModeBase::GetWidgetsManager()
|
||||||
{
|
{
|
||||||
return _widgetsManager;
|
return _widgetsManager.Get();
|
||||||
}
|
}
|
||||||
UCutsceneManager* AMainGameModeBase::GetCutsceneManager()
|
UCutsceneManager* AMainGameModeBase::GetCutsceneManager()
|
||||||
{
|
{
|
||||||
return _cutsceneManager;
|
return _cutsceneManager.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
UQuickTimeEventManager* AMainGameModeBase::GetQuickTimeEventManager()
|
||||||
|
{
|
||||||
|
return _quickTimeEventManager.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
UDialogueManager* AMainGameModeBase::GetDialogueManager()
|
UDialogueManager* AMainGameModeBase::GetDialogueManager()
|
||||||
{
|
{
|
||||||
return _dialogueManager;
|
return _dialogueManager.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMainGameModeBase::CallNextLevelState()
|
void AMainGameModeBase::CallNextLevelState()
|
||||||
|
@ -23,6 +23,8 @@ public:
|
|||||||
UFUNCTION(BlueprintPure)
|
UFUNCTION(BlueprintPure)
|
||||||
static class UCutsceneManager* GetCutsceneManager();
|
static class UCutsceneManager* GetCutsceneManager();
|
||||||
UFUNCTION(BlueprintPure)
|
UFUNCTION(BlueprintPure)
|
||||||
|
static class UQuickTimeEventManager* GetQuickTimeEventManager();
|
||||||
|
UFUNCTION(BlueprintPure)
|
||||||
static class UDialogueManager* GetDialogueManager();
|
static class UDialogueManager* GetDialogueManager();
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
@ -32,7 +34,7 @@ public:
|
|||||||
|
|
||||||
void SwitchCameraMode();
|
void SwitchCameraMode();
|
||||||
|
|
||||||
static class ALevelBase* leadLevel;
|
static TStrongObjectPtr<class ALevelBase> leadLevel;
|
||||||
|
|
||||||
FQuestsUpdateDelegate questsUpdateDelegate;
|
FQuestsUpdateDelegate questsUpdateDelegate;
|
||||||
|
|
||||||
@ -41,8 +43,9 @@ protected:
|
|||||||
TSubclassOf<class UWidgetsManager> widgetManagerClass;
|
TSubclassOf<class UWidgetsManager> widgetManagerClass;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static class UWidgetsManager* _widgetsManager;
|
static TStrongObjectPtr<class UWidgetsManager> _widgetsManager;
|
||||||
static class UCutsceneManager* _cutsceneManager;
|
static TStrongObjectPtr<class UCutsceneManager> _cutsceneManager;
|
||||||
static class UDialogueManager* _dialogueManager;
|
static TStrongObjectPtr<class UQuickTimeEventManager> _quickTimeEventManager;
|
||||||
static class UQuestManager* _questManager;
|
static TStrongObjectPtr<class UDialogueManager> _dialogueManager;
|
||||||
|
static TStrongObjectPtr<class UQuestManager> _questManager;
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "Kismet/GameplayStatics.h"
|
#include "Kismet/GameplayStatics.h"
|
||||||
#include "Kismet/KismetMathLibrary.h"
|
#include "Kismet/KismetMathLibrary.h"
|
||||||
|
|
||||||
|
|
||||||
#include "CustomGameInstanceBase.h"
|
#include "CustomGameInstanceBase.h"
|
||||||
#include "CustomGameUserSettings.h"
|
#include "CustomGameUserSettings.h"
|
||||||
#include "Interactable/Activators/InteractableActivator.h"
|
#include "Interactable/Activators/InteractableActivator.h"
|
||||||
@ -87,8 +88,6 @@ void APlayerBase::BeginPlay()
|
|||||||
playerController = Cast<APlayerController>(GetController());
|
playerController = Cast<APlayerController>(GetController());
|
||||||
if(playerController)
|
if(playerController)
|
||||||
{
|
{
|
||||||
inputComponent = Cast<UEnhancedInputComponent>(playerController->InputComponent);;
|
|
||||||
|
|
||||||
if(auto inputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(playerController->GetLocalPlayer()))
|
if(auto inputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(playerController->GetLocalPlayer()))
|
||||||
{
|
{
|
||||||
if(auto GI = Cast<UCustomGameInstanceBase>(GetWorld()->GetGameInstance()))
|
if(auto GI = Cast<UCustomGameInstanceBase>(GetWorld()->GetGameInstance()))
|
||||||
@ -100,11 +99,30 @@ void APlayerBase::BeginPlay()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inputComponent = Cast<UEnhancedInputComponent>(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();
|
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()
|
bool APlayerBase::IsMoving()
|
||||||
{
|
{
|
||||||
return bIsMoving;
|
return bIsMoving;
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
enum class EActivatorType : uint8;
|
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);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FPlayerMovedDelegate);
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
USTRUCT(BlueprintType)
|
||||||
@ -63,6 +65,9 @@ public:
|
|||||||
FPlayerMovedDelegate OnPlayerMoved;
|
FPlayerMovedDelegate OnPlayerMoved;
|
||||||
FVector moveVector;
|
FVector moveVector;
|
||||||
|
|
||||||
|
FPlayerAnyKeyPressedDelegate onAnyKeyPressedDelegate;
|
||||||
|
FPlayerAnyKeyReleasedDelegate onAnyKeyReleasedDelegate;
|
||||||
|
|
||||||
class UEnhancedInputComponent* inputComponent = nullptr;
|
class UEnhancedInputComponent* inputComponent = nullptr;
|
||||||
|
|
||||||
class AActor* leftPocketItem = nullptr;
|
class AActor* leftPocketItem = nullptr;
|
||||||
@ -71,6 +76,9 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
|
|
||||||
|
void OnAnyKeyPressed(FKey key);
|
||||||
|
void OnAnyKeyReleased(FKey key);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = CameraMode)
|
UFUNCTION(BlueprintCallable, Category = CameraMode)
|
||||||
void SwitchToCameraPawn();
|
void SwitchToCameraPawn();
|
||||||
|
|
||||||
|
182
Source/Lost_Edge/Private/QuickTimeEvent.cpp
Normal file
182
Source/Lost_Edge/Private/QuickTimeEvent.cpp
Normal file
@ -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);
|
||||||
|
}
|
95
Source/Lost_Edge/Private/QuickTimeEvent.h
Normal file
95
Source/Lost_Edge/Private/QuickTimeEvent.h
Normal file
@ -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<FQuickTimeEventEnqueProperties> _nextEvents;
|
||||||
|
TMap<int32, Event> _events;
|
||||||
|
FCriticalSection _lock;
|
||||||
|
};
|
@ -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<FColor*>((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<SAdvanceButton*>(MyButton.Get()))->hitboxTexture = hitboxTexture;
|
|
||||||
// (static_cast<SAdvanceButton*>(MyButton.Get()))->hitboxTextureAlphaThreshold = hitboxTextureAlphaThreshold;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//TSharedRef<SWidget> UAdvanceButton::RebuildWidget()
|
|
||||||
//{
|
|
||||||
// TSharedPtr<SAdvanceButton> 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<UButtonSlot>(GetContentSlot())->BuildSlot(MyButton.ToSharedRef());
|
|
||||||
//
|
|
||||||
// return MyButton.ToSharedRef();
|
|
||||||
//}
|
|
@ -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<IToolTip> 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<SWidget> 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;
|
|
||||||
};
|
|
58
Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.cpp
Normal file
58
Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.cpp
Normal file
@ -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);
|
||||||
|
}
|
54
Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.h
Normal file
54
Source/Lost_Edge/Private/Widgets/QuickTimeEventWidget.h
Normal file
@ -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;
|
||||||
|
};
|
@ -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<UQuickTimeEventWidget>(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<UQuickTimeEventWidget>(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);
|
||||||
|
}
|
@ -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<EQuickTimeEventType, TSubclassOf<UQuickTimeEventWidget>> eventWidgetClasses;
|
||||||
|
|
||||||
|
UPROPERTY(meta = (BindWidget))
|
||||||
|
class UCanvasPanel* canvas;
|
||||||
|
|
||||||
|
TMap<const int32, UQuickTimeEventWidget*> eventsMap;
|
||||||
|
FCriticalSection mappingLock;
|
||||||
|
};
|
@ -22,6 +22,7 @@
|
|||||||
#include "Widgets/InventoryWidget.h"
|
#include "Widgets/InventoryWidget.h"
|
||||||
#include "Widgets/JournalWidget.h"
|
#include "Widgets/JournalWidget.h"
|
||||||
#include "Widgets/MainMenu/MainMenuWidget.h"
|
#include "Widgets/MainMenu/MainMenuWidget.h"
|
||||||
|
#include "Widgets/QuickTimeEventWidgetManager.h"
|
||||||
|
|
||||||
void UWidgetsManager::Init()
|
void UWidgetsManager::Init()
|
||||||
{
|
{
|
||||||
@ -52,6 +53,7 @@ void UWidgetsManager::Init()
|
|||||||
if(auto instance = CreateWidget<UInteractableHintWidgetManager>(PC, interactableHintWidgetManagerClass))
|
if(auto instance = CreateWidget<UInteractableHintWidgetManager>(PC, interactableHintWidgetManagerClass))
|
||||||
{
|
{
|
||||||
interactableHintWidgetManager = instance;
|
interactableHintWidgetManager = instance;
|
||||||
|
interactableHintWidgetManager->SetVisibility(ESlateVisibility::Visible);
|
||||||
interactableHintWidgetManager->AddToViewport();
|
interactableHintWidgetManager->AddToViewport();
|
||||||
}
|
}
|
||||||
if(auto instance = CreateWidget<UCutsceneSkipWidget>(PC, cutsceneSkipWidgetClass))
|
if(auto instance = CreateWidget<UCutsceneSkipWidget>(PC, cutsceneSkipWidgetClass))
|
||||||
@ -60,6 +62,12 @@ void UWidgetsManager::Init()
|
|||||||
cutsceneSkipWidget->SetVisibility(ESlateVisibility::Hidden);
|
cutsceneSkipWidget->SetVisibility(ESlateVisibility::Hidden);
|
||||||
cutsceneSkipWidget->AddToViewport();
|
cutsceneSkipWidget->AddToViewport();
|
||||||
}
|
}
|
||||||
|
if(auto instance = CreateWidget<UQuickTimeEventWidgetManager>(PC, quickTimeEventWidgetManagerClass))
|
||||||
|
{
|
||||||
|
quickTimeEventWidgetManager = instance;
|
||||||
|
quickTimeEventWidgetManager->SetVisibility(ESlateVisibility::Visible);
|
||||||
|
quickTimeEventWidgetManager->AddToViewport();
|
||||||
|
}
|
||||||
if(auto instance = CreateWidget<UDialogueRowWidgetManager>(PC, dialogueRowWidgetManagerClass))
|
if(auto instance = CreateWidget<UDialogueRowWidgetManager>(PC, dialogueRowWidgetManagerClass))
|
||||||
{
|
{
|
||||||
dialogueRowWidgetManager = instance;
|
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)
|
void UWidgetsManager::SetInputDialogueWidget(const FKey key, const FText desc, FDialogueSkipDelegate& delegate)
|
||||||
{
|
{
|
||||||
dialogueRowWidgetManager->SetInput(key, desc, delegate);
|
dialogueRowWidgetManager->SetInput(key, desc, delegate);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "WidgetsManager.generated.h"
|
#include "WidgetsManager.generated.h"
|
||||||
|
|
||||||
enum class EInputAnimatedWidgetAnimation : uint8;
|
enum class EInputAnimatedWidgetAnimation : uint8;
|
||||||
|
enum class EQuickTimeEventResult : uint8;
|
||||||
|
|
||||||
UCLASS(Blueprintable)
|
UCLASS(Blueprintable)
|
||||||
class UWidgetsManager : public UObject
|
class UWidgetsManager : public UObject
|
||||||
@ -34,6 +35,10 @@ public:
|
|||||||
void DisableCutsceneWidget();
|
void DisableCutsceneWidget();
|
||||||
void AnimateCutsceneWidget(const EInputAnimatedWidgetAnimation animation);
|
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 SetInputDialogueWidget(const FKey key, const FText desc, class FDialogueSkipDelegate& delegate);
|
||||||
void ShowDialogueWidget(const struct FDialogueRow& dialogue);
|
void ShowDialogueWidget(const struct FDialogueRow& dialogue);
|
||||||
void HideDialogueWidget(const struct FDialogueRow& dialogue);
|
void HideDialogueWidget(const struct FDialogueRow& dialogue);
|
||||||
@ -68,6 +73,10 @@ protected:
|
|||||||
TSubclassOf<class UCutsceneSkipWidget> cutsceneSkipWidgetClass; // never hidden
|
TSubclassOf<class UCutsceneSkipWidget> cutsceneSkipWidgetClass; // never hidden
|
||||||
class UCutsceneSkipWidget* cutsceneSkipWidget = nullptr;
|
class UCutsceneSkipWidget* cutsceneSkipWidget = nullptr;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly)
|
||||||
|
TSubclassOf<class UQuickTimeEventWidgetManager> quickTimeEventWidgetManagerClass; // never hidden
|
||||||
|
class UQuickTimeEventWidgetManager* quickTimeEventWidgetManager = nullptr;
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly)
|
UPROPERTY(EditDefaultsOnly)
|
||||||
TSubclassOf<class UDialogueRowWidgetManager> dialogueRowWidgetManagerClass; // hidden in cutscene
|
TSubclassOf<class UDialogueRowWidgetManager> dialogueRowWidgetManagerClass; // hidden in cutscene
|
||||||
class UDialogueRowWidgetManager* dialogueRowWidgetManager = nullptr;
|
class UDialogueRowWidgetManager* dialogueRowWidgetManager = nullptr;
|
||||||
|
@ -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<UPanelWidget>(GetRootWidget()))
|
||||||
|
{
|
||||||
|
if(root->GetChildrenCount() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// recursion would be simplier...
|
||||||
|
TArray<int32> path{ 0 };
|
||||||
|
UWidget* widget = root->GetChildAt(0);
|
||||||
|
while(widget != root)
|
||||||
|
{
|
||||||
|
UpdateAnimation(widget, newSpeed);
|
||||||
|
|
||||||
|
if(path.Num() < maxDepth)
|
||||||
|
{
|
||||||
|
if(auto panel = Cast<UPanelWidget>(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<UUserWidget>(widget))
|
||||||
|
{
|
||||||
|
for(auto player : userWidget->ActiveSequencePlayers)
|
||||||
|
player->SetPlaybackSpeed(newSpeed);
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user