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
|
||||
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
|
||||
|
@ -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
|
||||
|
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 "UObject/Object.h"
|
||||
|
||||
#include "CustomGameInstanceBase.h"
|
||||
#include "Levels/LevelBase.h"
|
||||
#include "PlayerBase.h"
|
||||
|
||||
@ -42,17 +43,78 @@ void UCommonFunctions::DestroyActorRecursively(AActor* actor)
|
||||
|
||||
ALevelBase* UCommonFunctions::GetCurrentLevelScript(UObject* obj)
|
||||
{
|
||||
if(auto world = obj->GetWorld())
|
||||
if(auto level = world->GetCurrentLevel())
|
||||
if(auto script = level->GetLevelScriptActor())
|
||||
return Cast<ALevelBase>(script);
|
||||
if(obj)
|
||||
if(auto world = obj->GetWorld())
|
||||
if(auto level = world->GetCurrentLevel())
|
||||
if(auto script = level->GetLevelScriptActor())
|
||||
return Cast<ALevelBase>(script);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
APlayerBase* UCommonFunctions::GetPlayer(UObject* obj)
|
||||
{
|
||||
if(auto pc = UGameplayStatics::GetPlayerController(obj->GetWorld(), 0))
|
||||
if(auto pawn = pc->GetPawn())
|
||||
return Cast<APlayerBase>(pawn);
|
||||
if(obj)
|
||||
if(auto pc = UGameplayStatics::GetPlayerController(obj->GetWorld(), 0))
|
||||
if(auto pawn = pc->GetPawn())
|
||||
return Cast<APlayerBase>(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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -14,8 +14,6 @@
|
||||
|
||||
void ALevel3::BeginPlay()
|
||||
{
|
||||
AMainGameModeBase::leadLevel = this;
|
||||
|
||||
ALevelBase::BeginPlay();
|
||||
|
||||
CallNextState();
|
||||
|
@ -14,8 +14,6 @@
|
||||
|
||||
void ALevel4::BeginPlay()
|
||||
{
|
||||
AMainGameModeBase::leadLevel = this;
|
||||
|
||||
ALevelBase::BeginPlay();
|
||||
|
||||
CallNextState();
|
||||
|
@ -14,8 +14,6 @@
|
||||
|
||||
void ALevel5::BeginPlay()
|
||||
{
|
||||
AMainGameModeBase::leadLevel = this;
|
||||
|
||||
ALevelBase::BeginPlay();
|
||||
|
||||
CallNextState();
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
void ALevelBase::BeginPlay()
|
||||
{
|
||||
AMainGameModeBase::leadLevel = this;
|
||||
AMainGameModeBase::leadLevel = TStrongObjectPtr<ALevelBase>{ this };
|
||||
|
||||
if(auto world = GetWorld())
|
||||
{
|
||||
|
@ -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<UWidgetsManager> AMainGameModeBase::_widgetsManager = nullptr;
|
||||
TStrongObjectPtr<UCutsceneManager> AMainGameModeBase::_cutsceneManager = nullptr;
|
||||
TStrongObjectPtr<UQuickTimeEventManager> AMainGameModeBase::_quickTimeEventManager = nullptr;
|
||||
TStrongObjectPtr<UDialogueManager> AMainGameModeBase::_dialogueManager = nullptr;
|
||||
TStrongObjectPtr<UQuestManager> AMainGameModeBase::_questManager = nullptr;
|
||||
TStrongObjectPtr<ALevelBase> AMainGameModeBase::leadLevel = nullptr;
|
||||
|
||||
void AMainGameModeBase::StartPlay()
|
||||
{
|
||||
_widgetsManager = NewObject<UWidgetsManager>(this, widgetManagerClass);
|
||||
_cutsceneManager = NewObject<UCutsceneManager>(this);
|
||||
_dialogueManager = NewObject<UDialogueManager>(this);
|
||||
_questManager = NewObject<UQuestManager>(this);
|
||||
_widgetsManager = TStrongObjectPtr<UWidgetsManager>{ NewObject<UWidgetsManager>(this, widgetManagerClass) };
|
||||
_cutsceneManager = TStrongObjectPtr<UCutsceneManager>{ NewObject<UCutsceneManager>(this) };
|
||||
_quickTimeEventManager = TStrongObjectPtr<UQuickTimeEventManager>{ NewObject<UQuickTimeEventManager>(this) };
|
||||
_dialogueManager = TStrongObjectPtr<UDialogueManager>{ NewObject<UDialogueManager>(this) };
|
||||
_questManager = TStrongObjectPtr<UQuestManager>{ NewObject<UQuestManager>(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()
|
||||
|
@ -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<class ALevelBase> leadLevel;
|
||||
|
||||
FQuestsUpdateDelegate questsUpdateDelegate;
|
||||
|
||||
@ -41,8 +43,9 @@ protected:
|
||||
TSubclassOf<class UWidgetsManager> widgetManagerClass;
|
||||
|
||||
private:
|
||||
static class UWidgetsManager* _widgetsManager;
|
||||
static class UCutsceneManager* _cutsceneManager;
|
||||
static class UDialogueManager* _dialogueManager;
|
||||
static class UQuestManager* _questManager;
|
||||
static TStrongObjectPtr<class UWidgetsManager> _widgetsManager;
|
||||
static TStrongObjectPtr<class UCutsceneManager> _cutsceneManager;
|
||||
static TStrongObjectPtr<class UQuickTimeEventManager> _quickTimeEventManager;
|
||||
static TStrongObjectPtr<class UDialogueManager> _dialogueManager;
|
||||
static TStrongObjectPtr<class UQuestManager> _questManager;
|
||||
};
|
||||
|
@ -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<APlayerController>(GetController());
|
||||
if(playerController)
|
||||
{
|
||||
inputComponent = Cast<UEnhancedInputComponent>(playerController->InputComponent);;
|
||||
|
||||
if(auto inputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(playerController->GetLocalPlayer()))
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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();
|
||||
|
||||
|
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/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<UInteractableHintWidgetManager>(PC, interactableHintWidgetManagerClass))
|
||||
{
|
||||
interactableHintWidgetManager = instance;
|
||||
interactableHintWidgetManager->SetVisibility(ESlateVisibility::Visible);
|
||||
interactableHintWidgetManager->AddToViewport();
|
||||
}
|
||||
if(auto instance = CreateWidget<UCutsceneSkipWidget>(PC, cutsceneSkipWidgetClass))
|
||||
@ -60,6 +62,12 @@ void UWidgetsManager::Init()
|
||||
cutsceneSkipWidget->SetVisibility(ESlateVisibility::Hidden);
|
||||
cutsceneSkipWidget->AddToViewport();
|
||||
}
|
||||
if(auto instance = CreateWidget<UQuickTimeEventWidgetManager>(PC, quickTimeEventWidgetManagerClass))
|
||||
{
|
||||
quickTimeEventWidgetManager = instance;
|
||||
quickTimeEventWidgetManager->SetVisibility(ESlateVisibility::Visible);
|
||||
quickTimeEventWidgetManager->AddToViewport();
|
||||
}
|
||||
if(auto instance = CreateWidget<UDialogueRowWidgetManager>(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);
|
||||
|
@ -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<class UCutsceneSkipWidget> cutsceneSkipWidgetClass; // never hidden
|
||||
class UCutsceneSkipWidget* cutsceneSkipWidget = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
TSubclassOf<class UQuickTimeEventWidgetManager> quickTimeEventWidgetManagerClass; // never hidden
|
||||
class UQuickTimeEventWidgetManager* quickTimeEventWidgetManager = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
TSubclassOf<class UDialogueRowWidgetManager> dialogueRowWidgetManagerClass; // hidden in cutscene
|
||||
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