CustomGameInstance, CustomPlayerController

This commit is contained in:
Oleg Petruny 2024-12-13 00:20:57 +01:00
parent 39ab5e17a8
commit bb5ae58b06
33 changed files with 354 additions and 324 deletions

View File

@ -10,8 +10,8 @@
#include "InputMappingContext.h" #include "InputMappingContext.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "CustomGameInstanceBase.h"
#include "CustomGameUserSettings.h" #include "CustomGameUserSettings.h"
#include "CustomPlayerController.h"
#include "MainGameModeBase.h" #include "MainGameModeBase.h"
ACameraModeBase::ACameraModeBase() ACameraModeBase::ACameraModeBase()
@ -25,30 +25,12 @@ void ACameraModeBase::BeginPlay()
auto world = GetWorld(); auto world = GetWorld();
//GetMovementComponent()->speed
// GetCharacterMovement()->MaxWalkSpeed = moveSpeed;
auto gameSettings = UCustomGameUserSettings::GetCustomGameUserSettings(); auto gameSettings = UCustomGameUserSettings::GetCustomGameUserSettings();
if(auto camera = FindComponentByClass<UCameraComponent>()) if(auto camera = FindComponentByClass<UCameraComponent>())
{ {
camera->PostProcessSettings.MotionBlurAmount = gameSettings->bUseMotionBlur ? 1.0f : 0.0f; camera->PostProcessSettings.MotionBlurAmount = gameSettings->bUseMotionBlur ? 1.0f : 0.0f;
} }
if(auto PC = Cast<APlayerController>(GetController()))
{
if(auto inputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer()))
{
if(auto GI = UCustomGameInstanceBase::GetGameInstance())
{
inputSubsystem->ClearAllMappings();
for(auto& inputContext : GI->inputContexts)
{
inputSubsystem->AddMappingContext(inputContext.LoadSynchronous(), 0);
}
}
}
}
} }
void ACameraModeBase::Tick(float DeltaTime) void ACameraModeBase::Tick(float DeltaTime)

View File

@ -7,7 +7,7 @@
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "UObject/Object.h" #include "UObject/Object.h"
#include "CustomGameInstanceBase.h" #include "CustomGameInstance.h"
#include "Levels/LevelBase.h" #include "Levels/LevelBase.h"
#include "PlayerBase.h" #include "PlayerBase.h"
@ -86,7 +86,7 @@ void UCommonFunctions::EnterSlowMotion(float duration)
SlowMotion::targetDilation = SlowMotion::slowDilation; SlowMotion::targetDilation = SlowMotion::slowDilation;
auto GI = UCustomGameInstanceBase::GetGameInstance(); auto GI = UCustomGameInstance::GetGameInstance();
if(!GI) if(!GI)
return; return;
@ -101,7 +101,7 @@ void UCommonFunctions::ExitSlowMotion(float duration)
SlowMotion::targetDilation = SlowMotion::normalDilation; SlowMotion::targetDilation = SlowMotion::normalDilation;
auto GI = UCustomGameInstanceBase::GetGameInstance(); auto GI = UCustomGameInstance::GetGameInstance();
if(!GI) if(!GI)
return; return;
@ -116,7 +116,7 @@ FWorldDilationChangedDelegate& UCommonFunctions::GetWorldDilationChangedDelegate
void UCommonFunctions::SlowMotionTick() void UCommonFunctions::SlowMotionTick()
{ {
const UWorld* world = UCustomGameInstanceBase::GetGameInstance()->GetWorld(); const UWorld* world = UCustomGameInstance::GetGameInstance()->GetWorld();
const float currentDilation = UGameplayStatics::GetGlobalTimeDilation(world); const float currentDilation = UGameplayStatics::GetGlobalTimeDilation(world);
float newDilation = FMath::FInterpTo(currentDilation, SlowMotion::targetDilation, 1, SlowMotion::interpolationSpeed); float newDilation = FMath::FInterpTo(currentDilation, SlowMotion::targetDilation, 1, SlowMotion::interpolationSpeed);

View File

@ -0,0 +1,74 @@
// Oleg Petruny proprietary.
#include "CustomGameInstance.h"
#include "Kismet/GameplayStatics.h"
#include "Kismet/KismetSystemLibrary.h"
#include "CommonFunctions.h"
#include "ContentLoader.h"
#include "Levels/LevelBase.h"
#include "PlayerBase.h"
#include "SaveData.h"
UCustomGameInstance* UCustomGameInstance::instance = nullptr;
void UCustomGameInstance::Init()
{
UGameInstance::Init();
instance = this;
contentLoader = NewObject<UContentLoader>(this);
saveData = Cast<USaveData>(UGameplayStatics::CreateSaveGameObject(USaveData::StaticClass()));
}
UCustomGameInstance* UCustomGameInstance::GetGameInstance()
{
return instance;
}
UContentLoader* UCustomGameInstance::GetContentLoader()
{
if(auto GI = GetGameInstance())
return GI->contentLoader;
return nullptr;
}
void UCustomGameInstance::SaveGame(FName checkpointName)
{
auto levelScript = UCommonFunctions::GetCurrentLevelScript(this);
if(!levelScript)
return;
auto player = UCommonFunctions::GetPlayer(this);
if(!player)
return;
saveData->level = GetWorld()->GetFName();
saveData->state = levelScript->GetState();
saveData->checkpoint = checkpointName;
if(player->leftPocketItem)
saveData->playerLeftPocketItem = player->leftPocketItem->GetFName();
else
saveData->playerLeftPocketItem = FName(TEXT(""));
if(player->rightPocketItem)
saveData->playerRightPocketItem = player->rightPocketItem->GetFName();
else
saveData->playerRightPocketItem = FName(TEXT(""));
UGameplayStatics::SaveGameToSlot(saveData, TEXT("Save"), 0);
}
void UCustomGameInstance::LoadGame()
{
saveData = Cast<USaveData>(UGameplayStatics::LoadGameFromSlot(TEXT("Save"), 0));
if(!saveData)
return;
UGameplayStatics::OpenLevel(this, saveData->level);
}
void UCustomGameInstance::ExitGame()
{
UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, true);
}

View File

@ -4,29 +4,29 @@
#include "Engine/GameInstance.h" #include "Engine/GameInstance.h"
#include "CustomGameInstanceBase.generated.h" #include "CustomGameInstance.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FLevelBeginnedDelegate, FName, levelName); DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FLevelBeginnedDelegate, FName, levelName);
/**
* Expands basic UE game instance.
* Manages saves, handles content loader and can shutdown the game.
*/
UCLASS() UCLASS()
class UCustomGameInstanceBase : public UGameInstance class UCustomGameInstance : public UGameInstance
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
/** Instantiates content loader, dummy save data and applies settings */
virtual void Init() override; virtual void Init() override;
UFUNCTION(BlueprintPure) UFUNCTION(BlueprintPure)
static UCustomGameInstanceBase* GetGameInstance(); static UCustomGameInstance* GetGameInstance();
UFUNCTION(BlueprintPure) UFUNCTION(BlueprintPure)
static class UContentLoader* GetContentLoader(); static class UContentLoader* GetContentLoader();
UFUNCTION(BlueprintCallable, Category = Settings)
void ApplyMouseSettings();
void AppendInteractableModificatorClass(TSubclassOf<class UInteractableModificator> modificator);
UFUNCTION(BlueprintCallable, Category = Save) UFUNCTION(BlueprintCallable, Category = Save)
void SaveGame(FName checkpointName); void SaveGame(FName checkpointName);
UFUNCTION(BlueprintCallable, Category = Save) UFUNCTION(BlueprintCallable, Category = Save)
@ -34,17 +34,11 @@ public:
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
void ExitGame(); void ExitGame();
static UCustomGameInstanceBase* instance; static UCustomGameInstance* instance;
/** Public delegate called by ALevelBase instance on instantiation */
FLevelBeginnedDelegate OnLevelBeginned; FLevelBeginnedDelegate OnLevelBeginned;
UPROPERTY(EditDefaultsOnly)
TSet<TSubclassOf<class UInteractableActivator>> interactionsActivators;
TSet<TSubclassOf<class UInteractableModificator>> interactionsModificators;
UPROPERTY(EditDefaultsOnly)
TSet<TSoftObjectPtr<class UInputMappingContext>> inputContexts;
UPROPERTY(VisibleAnywhere) UPROPERTY(VisibleAnywhere)
class USaveData* saveData = nullptr; class USaveData* saveData = nullptr;

View File

@ -1,148 +0,0 @@
// Oleg Petruny proprietary.
#include "CustomGameInstanceBase.h"
#include "EnhancedInputLibrary.h"
#include "EnhancedInputSubsystems.h"
#include "InputMappingContext.h"
#include "Kismet/GameplayStatics.h"
#include "Kismet/KismetSystemLibrary.h"
#include "CommonFunctions.h"
#include "ContentLoader.h"
#include "CustomGameUserSettings.h"
#include "Interactable/Activators/InCameraInteractableActivator.h"
#include "Interactable/Activators/RaycastInteractableActivator.h"
#include "Interactable/Modificators/ActivateInteractableModificator.h"
#include "Interactable/Modificators/SawInteractableModificator.h"
#include "Levels/LevelBase.h"
#include "PlayerBase.h"
#include "SaveData.h"
UCustomGameInstanceBase* UCustomGameInstanceBase::instance = nullptr;
void UCustomGameInstanceBase::Init()
{
UGameInstance::Init();
instance = this;
contentLoader = NewObject<UContentLoader>(this);
interactionsActivators.Add(URaycastInteractableActivator::StaticClass());
interactionsActivators.Add(UInCameraInteractableActivator::StaticClass());
for(auto& modificator : interactionsModificators)
{
if(modificator.GetDefaultObject()->GetMappingContext())
{
inputContexts.Add(modificator.GetDefaultObject()->GetMappingContext());
}
}
ApplyMouseSettings();
saveData = Cast<USaveData>(UGameplayStatics::CreateSaveGameObject(USaveData::StaticClass()));
}
UCustomGameInstanceBase* UCustomGameInstanceBase::GetGameInstance()
{
return instance;
}
UContentLoader* UCustomGameInstanceBase::GetContentLoader()
{
if(auto GI = GetGameInstance())
return GI->contentLoader;
return nullptr;
}
void UCustomGameInstanceBase::ApplyMouseSettings()
{
if(auto gameSettings = UCustomGameUserSettings::GetCustomGameUserSettings())
{
for(auto& context : inputContexts)
{
if(!context.LoadSynchronous())
continue;
for(auto& mapping : context.LoadSynchronous()->GetMappings())
{
if(mapping.Key == EKeys::Mouse2D)
{
for(auto& modifier : mapping.Modifiers)
{
if(auto negate_modifier = Cast<UInputModifierNegate>(modifier))
{
negate_modifier->bY = !gameSettings->bMouseInverted;
}
if(auto scalar_modifier = Cast<UInputModifierScalar>(modifier))
{
scalar_modifier->Scalar = FVector{ gameSettings->GetMouseSensetivity() * 0.5 };
}
}
}
}
UEnhancedInputLibrary::RequestRebuildControlMappingsUsingContext(context.LoadSynchronous());
}
}
}
void UCustomGameInstanceBase::AppendInteractableModificatorClass(TSubclassOf<class UInteractableModificator> modificator)
{
bool alreadyPresent = false;
interactionsModificators.Add(modificator, &alreadyPresent);
if(!alreadyPresent)
{
if(auto IC = modificator.GetDefaultObject()->GetMappingContext())
{
inputContexts.Add(IC);
if(auto PC = UGameplayStatics::GetPlayerController(GetWorld(), 0))
{
if(auto inputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer()))
{
inputSubsystem->AddMappingContext(IC, 0);
}
}
}
}
}
void UCustomGameInstanceBase::SaveGame(FName checkpointName)
{
auto levelScript = UCommonFunctions::GetCurrentLevelScript(this);
if(!levelScript)
return;
auto player = UCommonFunctions::GetPlayer(this);
if(!player)
return;
saveData->level = GetWorld()->GetFName();
saveData->state = levelScript->GetState();
saveData->checkpoint = checkpointName;
if(player->leftPocketItem)
saveData->playerLeftPocketItem = player->leftPocketItem->GetFName();
else
saveData->playerLeftPocketItem = FName(TEXT(""));
if(player->rightPocketItem)
saveData->playerRightPocketItem = player->rightPocketItem->GetFName();
else
saveData->playerRightPocketItem = FName(TEXT(""));
UGameplayStatics::SaveGameToSlot(saveData, TEXT("Save"), 0);
}
void UCustomGameInstanceBase::LoadGame()
{
saveData = Cast<USaveData>(UGameplayStatics::LoadGameFromSlot(TEXT("Save"), 0));
if(!saveData)
return;
UGameplayStatics::OpenLevel(this, saveData->level);
}
void UCustomGameInstanceBase::ExitGame()
{
UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, true);
}

View File

@ -0,0 +1,90 @@
// Oleg Petruny proprietary.
#include "CustomPlayerController.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputLibrary.h"
#include "EnhancedInputSubsystems.h"
#include "InputMappingContext.h"
#include "CustomGameUserSettings.h"
ACustomPlayerController* ACustomPlayerController::instance = nullptr;
UEnhancedInputLocalPlayerSubsystem* ACustomPlayerController::subsystem = nullptr;
UEnhancedInputComponent* ACustomPlayerController::input = nullptr;
TSet<TSoftObjectPtr<UInputMappingContext>> ACustomPlayerController::contexts = {};
void ACustomPlayerController::AppendInputContext(TSoftObjectPtr<class UInputMappingContext> context)
{
if(!context.IsValid())
return;
ApplyMouseSettings(context);
contexts.Add(context);
if(subsystem)
subsystem->AddMappingContext(context.LoadSynchronous(), 0);
}
void ACustomPlayerController::BeginPlay()
{
instance = this;
subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(instance->GetLocalPlayer());
if(subsystem)
{
subsystem->ClearAllMappings();
for(auto& inputContext : contexts)
subsystem->AddMappingContext(inputContext.LoadSynchronous(), 0);
}
input = Cast<UEnhancedInputComponent>(InputComponent);
if(input)
{
((UInputComponent*)input)->BindAction(TEXT("AnyKey"), IE_Pressed, this, &ACustomPlayerController::OnAnyKeyPressed);
((UInputComponent*)input)->BindAction(TEXT("AnyKey"), IE_Released, this, &ACustomPlayerController::OnAnyKeyReleased);
}
}
void ACustomPlayerController::ApplyMouseSettings(TSoftObjectPtr<class UInputMappingContext>& context)
{
auto gameSettings = UCustomGameUserSettings::GetCustomGameUserSettings();
if(!gameSettings)
return;
if(!context.LoadSynchronous())
return;
for(auto& mapping : context.LoadSynchronous()->GetMappings())
{
if(mapping.Key != EKeys::Mouse2D)
continue;
for(auto& modifier : mapping.Modifiers)
{
if(gameSettings->bMouseInverted)
{
if(auto negate_modifier = Cast<UInputModifierNegate>(modifier))
{
negate_modifier->bY = !negate_modifier->bY;
continue;
}
}
if(auto scalar_modifier = Cast<UInputModifierScalar>(modifier))
scalar_modifier->Scalar = FVector{ gameSettings->GetMouseSensetivity() * 0.5 };
}
}
UEnhancedInputLibrary::RequestRebuildControlMappingsUsingContext(context.LoadSynchronous());
}
void ACustomPlayerController::OnAnyKeyPressed(FKey key)
{
if(onAnyKeyPressed.IsBound())
onAnyKeyPressed.Broadcast(key);
}
void ACustomPlayerController::OnAnyKeyReleased(FKey key)
{
if(onAnyKeyReleased.IsBound())
onAnyKeyReleased.Broadcast(key);
}

View File

@ -0,0 +1,49 @@
// Oleg Petruny proprietary.
#pragma once
#include "GameFramework/PlayerController.h"
#include "CustomPlayerController.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPlayerAnyKeyPressedDelegate, FKey, key);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPlayerAnyKeyReleasedDelegate, FKey, key);
/**
* De-facto wrapper/interface of all usefull shortcuts and automatization around input system.
* Append new input context here for auto init on BeginPlay and apply user input settings.
* Also, has delegates onAnyKeyPressed/Released.
*/
UCLASS()
class ACustomPlayerController : public APlayerController
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintPure, meta = (DisplayName = "GetCustomPlayerController"))
static ACustomPlayerController* Get() { return instance; }
UFUNCTION(BlueprintPure)
static class UEnhancedInputComponent* GetInput() { return input; }
UFUNCTION(BlueprintPure)
static class UEnhancedInputLocalPlayerSubsystem* GetInputSubsystem() { return subsystem; }
UFUNCTION(BlueprintCallable)
static void AppendInputContext(TSoftObjectPtr<class UInputMappingContext> context);
FPlayerAnyKeyPressedDelegate onAnyKeyPressed;
FPlayerAnyKeyReleasedDelegate onAnyKeyReleased;
protected:
virtual void BeginPlay() override;
private:
static void ApplyMouseSettings(TSoftObjectPtr<class UInputMappingContext>& context);
void OnAnyKeyPressed(FKey key);
void OnAnyKeyReleased(FKey key);
static ACustomPlayerController* instance;
static class UEnhancedInputLocalPlayerSubsystem* subsystem;
static class UEnhancedInputComponent* input;
static TSet<TSoftObjectPtr<class UInputMappingContext>> contexts;
};

View File

@ -9,7 +9,7 @@
#include "LevelSequence.h" #include "LevelSequence.h"
#include "LevelSequencePlayer.h" #include "LevelSequencePlayer.h"
#include "CustomGameInstanceBase.h" #include "CustomPlayerController.h"
#include "MainGameModeBase.h" #include "MainGameModeBase.h"
#include "PlayerBase.h" #include "PlayerBase.h"
#include "Widgets/CutsceneSkipWidget.h" #include "Widgets/CutsceneSkipWidget.h"
@ -20,10 +20,7 @@ UCutsceneManager::UCutsceneManager()
{ {
static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/IMC_Cutscene.IMC_Cutscene'") }; static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/IMC_Cutscene.IMC_Cutscene'") };
_inputContext = asset.Object; _inputContext = asset.Object;
if(auto GI = UCustomGameInstanceBase::GetGameInstance()) ACustomPlayerController::AppendInputContext(_inputContext);
{
GI->inputContexts.Add(_inputContext);
}
} }
void UCutsceneManager::EnqueueSequence(ULevelSequence* sequence, FCutsceneEndCallback endCallback) void UCutsceneManager::EnqueueSequence(ULevelSequence* sequence, FCutsceneEndCallback endCallback)
@ -44,8 +41,9 @@ void UCutsceneManager::EnqueueSequence(ULevelSequence* sequence, FCutsceneEndCal
_lastPlayer->LockPlayer({ .walk = true, .jump = true, .run = true, .interaction = true, .camera = true }); _lastPlayer->LockPlayer({ .walk = true, .jump = true, .run = true, .interaction = true, .camera = true });
auto& mapping = _inputContext.LoadSynchronous()->GetMapping(0); auto& mapping = _inputContext.LoadSynchronous()->GetMapping(0);
int32 handler1 = _lastPlayer->inputComponent->BindAction(mapping.Action, ETriggerEvent::Started, this, &UCutsceneManager::OnInputHold).GetHandle(); auto input = ACustomPlayerController::GetInput();
int32 handler2 = _lastPlayer->inputComponent->BindAction(mapping.Action, ETriggerEvent::Completed, this, &UCutsceneManager::OnInputUnhold).GetHandle(); int32 handler1 = input->BindAction(mapping.Action, ETriggerEvent::Started, this, &UCutsceneManager::OnInputHold).GetHandle();
int32 handler2 = input->BindAction(mapping.Action, ETriggerEvent::Completed, this, &UCutsceneManager::OnInputUnhold).GetHandle();
_handlers = { handler1, handler2 }; _handlers = { handler1, handler2 };
if(auto WM = AMainGameModeBase::GetWidgetsManager()) if(auto WM = AMainGameModeBase::GetWidgetsManager())
@ -148,8 +146,9 @@ void UCutsceneManager::OnSequenceEnd()
{ {
_lastPlayer->UnlockPlayer({ .walk = true, .jump = true, .run = true, .interaction = true, .camera = true }); _lastPlayer->UnlockPlayer({ .walk = true, .jump = true, .run = true, .interaction = true, .camera = true });
_lastPlayer->inputComponent->RemoveBindingByHandle(_handlers.Key); auto input = ACustomPlayerController::GetInput();
_lastPlayer->inputComponent->RemoveBindingByHandle(_handlers.Value); input->RemoveBindingByHandle(_handlers.Key);
input->RemoveBindingByHandle(_handlers.Value);
_lastPlayer = nullptr; _lastPlayer = nullptr;
} }

View File

@ -11,7 +11,7 @@
#include "Kismet/KismetMathLibrary.h" #include "Kismet/KismetMathLibrary.h"
#include "Sound/SoundWave.h" #include "Sound/SoundWave.h"
#include "CustomGameInstanceBase.h" #include "CustomPlayerController.h"
#include "MainGameModeBase.h" #include "MainGameModeBase.h"
#include "PlayerBase.h" #include "PlayerBase.h"
#include "Widgets/DialogueSkipWidget.h" #include "Widgets/DialogueSkipWidget.h"
@ -22,10 +22,7 @@ UDialogueManager::UDialogueManager()
{ {
static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/IMC_Dialogue.IMC_Dialogue'") }; static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/IMC_Dialogue.IMC_Dialogue'") };
_inputContext = asset.Object; _inputContext = asset.Object;
if(auto GI = UCustomGameInstanceBase::GetGameInstance()) ACustomPlayerController::AppendInputContext(_inputContext);
{
GI->inputContexts.Add(_inputContext);
}
} }
void UDialogueManager::PlayDialogue(FDialogueEnqueProperties properties, FDialogueEndCallback endCallback) void UDialogueManager::PlayDialogue(FDialogueEnqueProperties properties, FDialogueEndCallback endCallback)
@ -96,7 +93,7 @@ void UDialogueManager::EnqueDialogue(FDialogueEnqueProperties properties, FDialo
if(_lastPlayer) if(_lastPlayer)
{ {
auto& mapping = _inputContext.LoadSynchronous()->GetMapping(0); auto& mapping = _inputContext.LoadSynchronous()->GetMapping(0);
_inputHandler = _lastPlayer->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &UDialogueManager::OnInputPress).GetHandle(); _inputHandler = ACustomPlayerController::GetInput()->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &UDialogueManager::OnInputPress).GetHandle();
if(auto WM = AMainGameModeBase::GetWidgetsManager()) if(auto WM = AMainGameModeBase::GetWidgetsManager())
{ {
@ -258,7 +255,7 @@ void UDialogueManager::OnDialogueEnd()
_dialoguesLock.Lock(); _dialoguesLock.Lock();
if(_endCallbacks.IsEmpty() && _lastPlayer) if(_endCallbacks.IsEmpty() && _lastPlayer)
{ {
_lastPlayer->inputComponent->RemoveBindingByHandle(_inputHandler); ACustomPlayerController::GetInput()->RemoveBindingByHandle(_inputHandler);
_lastPlayer = nullptr; _lastPlayer = nullptr;
} }
_dialoguesLock.Unlock(); _dialoguesLock.Unlock();

View File

@ -30,7 +30,7 @@ UInCameraInteractableActivator::UInCameraInteractableActivator(const FObjectInit
void UInCameraInteractableActivator::OnRegister() void UInCameraInteractableActivator::OnRegister()
{ {
UInteractableActivator::OnRegister(); Super::OnRegister();
capturer->RegisterComponent(); capturer->RegisterComponent();
capturer->Activate(); capturer->Activate();
} }

View File

@ -20,6 +20,8 @@ public:
protected: protected:
virtual void OnRegister() override; virtual void OnRegister() override;
virtual bool AutoInstantiateInPlayer() override { return true; }
/** /**
* Scan is performed independently by _capturer member object. * Scan is performed independently by _capturer member object.
* This implementation just activates interactables in the game thread. * This implementation just activates interactables in the game thread.

View File

@ -4,8 +4,16 @@
#include "Engine/CollisionProfile.h" #include "Engine/CollisionProfile.h"
#include "Interactable/Interactable.h"
#include "PlayerBase.h" #include "PlayerBase.h"
void UInteractableActivator::OnRegister()
{
Super::OnRegister();
AInteractable::AppendInteractableActivatorClass(GetClass());
}
UInteractableActivator::UInteractableActivator(const FObjectInitializer& ObjectInitializer) UInteractableActivator::UInteractableActivator(const FObjectInitializer& ObjectInitializer)
: USceneComponent(ObjectInitializer) : USceneComponent(ObjectInitializer)
{ {

View File

@ -20,9 +20,14 @@ class UInteractableActivator : public USceneComponent
GENERATED_BODY() GENERATED_BODY()
public: public:
/** Append itself to CustomGameInstance modificators registry */
virtual void OnRegister() override;
UInteractableActivator(const FObjectInitializer& ObjectInitializer); UInteractableActivator(const FObjectInitializer& ObjectInitializer);
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
virtual bool AutoInstantiateInPlayer() { return false; }
/** Resets activator state forcing to rescan */ /** Resets activator state forcing to rescan */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable) UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
LOST_EDGE_API void Rescan(); LOST_EDGE_API void Rescan();

View File

@ -17,6 +17,8 @@ class URaycastInteractableActivator : public UInteractableActivator
public: public:
URaycastInteractableActivator(const FObjectInitializer& ObjectInitializer); URaycastInteractableActivator(const FObjectInitializer& ObjectInitializer);
virtual bool AutoInstantiateInPlayer() override { return true; }
virtual void Rescan_Implementation() override; virtual void Rescan_Implementation() override;
protected: protected:

View File

@ -4,11 +4,32 @@
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "Activators/InteractableActivator.h"
#include "CustomPlayerController.h"
#include "MainGameModeBase.h" #include "MainGameModeBase.h"
#include "Modificators/InteractableModificator.h" #include "Modificators/InteractableModificator.h"
#include "PlayerBase.h" #include "PlayerBase.h"
#include "Widgets/WidgetsManager.h" #include "Widgets/WidgetsManager.h"
TSet<TSubclassOf<class UInteractableActivator>> AInteractable::interactionActivators = {};
TSet<TSubclassOf<class UInteractableModificator>> AInteractable::interactionModificators = {};
void AInteractable::AppendInteractableActivatorClass(TSubclassOf<class UInteractableActivator> activator)
{
interactionActivators.Add(activator);
}
void AInteractable::AppendInteractableModificatorClass(TSubclassOf<class UInteractableModificator> modificator)
{
bool alreadyPresent = false;
interactionModificators.Add(modificator, &alreadyPresent);
if(alreadyPresent)
return;
auto IC = modificator.GetDefaultObject()->GetMappingContext();
ACustomPlayerController::AppendInputContext(IC);
}
int32 AInteractable::GetActivatedFlags() int32 AInteractable::GetActivatedFlags()
{ {
return activated; return activated;
@ -112,7 +133,7 @@ void AInteractable::Activate(EActivatorType type)
if(static_cast<uint8>(modificator.Value->GetActivatorTypes()) & static_cast<uint8>(type)) if(static_cast<uint8>(modificator.Value->GetActivatorTypes()) & static_cast<uint8>(type))
{ {
WM->ShowInteractionHints(modificator.Value); WM->ShowInteractionHints(modificator.Value);
modificator.Value->Bind(player->inputComponent); modificator.Value->Bind(ACustomPlayerController::GetInput());
} }
} }
} }

View File

@ -40,6 +40,15 @@ class AInteractable : public AActor
GENERATED_BODY() GENERATED_BODY()
public: public:
static void AppendInteractableActivatorClass(TSubclassOf<class UInteractableActivator> activator);
static void AppendInteractableModificatorClass(TSubclassOf<class UInteractableModificator> modificator);
/** Interactables shared cache */
static TSet<TSubclassOf<class UInteractableActivator>> interactionActivators;
static TSet<TSubclassOf<class UInteractableModificator>> interactionModificators;
public:
/** Returns flags mask of activated types */ /** Returns flags mask of activated types */
int32 GetActivatedFlags(); int32 GetActivatedFlags();

View File

@ -2,24 +2,19 @@
#include "InteractableModificator.h" #include "InteractableModificator.h"
#include "InputMappingContext.h" #include "Interactable/Interactable.h"
#include "CustomGameInstanceBase.h"
#include "Widgets/InteractableHintWidget.h" #include "Widgets/InteractableHintWidget.h"
void UInteractableModificator::OnRegister() void UInteractableModificator::OnRegister()
{ {
UActorComponent::OnRegister(); UActorComponent::OnRegister();
if(auto GI = UCustomGameInstanceBase::GetGameInstance()) AInteractable::AppendInteractableModificatorClass(GetClass());
{
GI->AppendInteractableModificatorClass(this->GetClass());
}
} }
const UInputMappingContext* UInteractableModificator::GetMappingContext() const const TSoftObjectPtr<class UInputMappingContext> UInteractableModificator::GetMappingContext() const
{ {
return inputMapping.LoadSynchronous(); return inputMapping;
} }
EActivatorType UInteractableModificator::GetActivatorTypes() const EActivatorType UInteractableModificator::GetActivatorTypes() const

View File

@ -18,11 +18,11 @@ class UInteractableModificator : public UActorComponent
public: public:
/** Append itself to CustomGameInstance modificators registry */ /** Append itself to CustomGameInstance modificators registry */
void OnRegister() override; virtual void OnRegister() override;
/** Returns input mappings assigned in constructor */ /** Returns input mappings assigned in constructor */
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
const class UInputMappingContext* GetMappingContext() const; const TSoftObjectPtr<class UInputMappingContext> GetMappingContext() const;
/** Filters activation type in interractable */ /** Filters activation type in interractable */
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)

View File

@ -2,10 +2,10 @@
#include "Checkpoint.h" #include "Checkpoint.h"
#include "CustomGameInstanceBase.h" #include "CustomGameInstance.h"
void ACheckpoint::SaveGame() void ACheckpoint::SaveGame()
{ {
if(auto GI = UCustomGameInstanceBase::GetGameInstance()) if(auto GI = UCustomGameInstance::GetGameInstance())
GI->SaveGame(GetFName()); GI->SaveGame(GetFName());
} }

View File

@ -10,7 +10,8 @@
#include "LevelSequencePlayer.h" #include "LevelSequencePlayer.h"
#include "CommonFunctions.h" #include "CommonFunctions.h"
#include "CustomGameInstanceBase.h" #include "CustomGameInstance.h"
#include "CustomPlayerController.h"
#include "Interactable/Interactable.h" #include "Interactable/Interactable.h"
#include "Levels/Checkpoint.h" #include "Levels/Checkpoint.h"
#include "MainGameModeBase.h" #include "MainGameModeBase.h"
@ -22,13 +23,8 @@ void ALevelBase::BeginPlay()
{ {
AMainGameModeBase::leadLevel = TStrongObjectPtr<ALevelBase>{ this }; AMainGameModeBase::leadLevel = TStrongObjectPtr<ALevelBase>{ this };
if(auto GI = UCustomGameInstanceBase::GetGameInstance()) for(TActorIterator<AMinigame> it(GetWorld()); it; ++it)
{ ACustomPlayerController::AppendInputContext(it->GetInputMappings());
for(TActorIterator<AMinigame> it(GetWorld()); it; ++it)
{
GI->inputContexts.Add(it->GetInputMappings());
}
}
ALevelScriptActor::BeginPlay(); ALevelScriptActor::BeginPlay();
@ -58,7 +54,7 @@ void ALevelBase::IterateToState(int32 to)
void ALevelBase::BroadcastNewLevelBeginPlay() void ALevelBase::BroadcastNewLevelBeginPlay()
{ {
if(auto GI = UCustomGameInstanceBase::GetGameInstance()) if(auto GI = UCustomGameInstance::GetGameInstance())
GI->OnLevelBeginned.Broadcast(GetFName()); GI->OnLevelBeginned.Broadcast(GetFName());
} }
@ -79,7 +75,7 @@ void ALevelBase::StartLevelAnimations()
void ALevelBase::ApplySaveData() void ALevelBase::ApplySaveData()
{ {
auto GI = UCustomGameInstanceBase::GetGameInstance(); auto GI = UCustomGameInstance::GetGameInstance();
if(!GI || !GI->saveData || GI->saveData->level != GetWorld()->GetFName()) if(!GI || !GI->saveData || GI->saveData->level != GetWorld()->GetFName())
return; return;

View File

@ -8,7 +8,7 @@
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "UObject/ScriptInterface.h" #include "UObject/ScriptInterface.h"
#include "CustomGameInstanceBase.h" #include "CustomGameInstance.h"
#include "CutsceneManager.h" #include "CutsceneManager.h"
#include "DialogueManager.h" #include "DialogueManager.h"
#include "Levels/LevelBase.h" #include "Levels/LevelBase.h"

View File

@ -10,7 +10,7 @@
#include "InputMappingContext.h" #include "InputMappingContext.h"
#include "CrossyRoadObstacle.h" #include "CrossyRoadObstacle.h"
#include "CustomGameInstanceBase.h" #include "CustomPlayerController.h"
#include "MainGameModeBase.h" #include "MainGameModeBase.h"
#include "PlayerBase.h" #include "PlayerBase.h"
#include "Widgets/WidgetsManager.h" #include "Widgets/WidgetsManager.h"
@ -19,7 +19,7 @@ ACrossyRoadManager::ACrossyRoadManager()
: AMinigame() : AMinigame()
{ {
static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/Minigame/IMC_Minigame_CrossyRoad.IMC_Minigame_CrossyRoad'") }; static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/Minigame/IMC_Minigame_CrossyRoad.IMC_Minigame_CrossyRoad'") };
input = asset.Object; context = asset.Object;
auto root = CreateDefaultSubobject<USceneComponent>(TEXT("Scene")); auto root = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
@ -43,16 +43,17 @@ void ACrossyRoadManager::Start(APlayerBase* playerPawn, FMinigameEndCallback del
player->LockPlayer(FPlayerLock::All()); player->LockPlayer(FPlayerLock::All());
player->SwitchToView(this); player->SwitchToView(this);
for(auto& mapping : input.LoadSynchronous()->GetMappings()) auto input = ACustomPlayerController::GetInput();
for(auto& mapping : context.LoadSynchronous()->GetMappings())
{ {
if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Up")))) if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Up"))))
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Up).GetHandle()); inputHandlers.Add(input->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Up).GetHandle());
else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Down")))) else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Down"))))
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Down).GetHandle()); inputHandlers.Add(input->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Down).GetHandle());
else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Left")))) else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Left"))))
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Left).GetHandle()); inputHandlers.Add(input->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Left).GetHandle());
else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Right")))) else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Right"))))
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Right).GetHandle()); inputHandlers.Add(input->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Right).GetHandle());
} }
playerPos->SetWorldLocation(lines[0]->GetLocationAtTime(lines[0]->Duration * playerLineTime, ESplineCoordinateSpace::World)); playerPos->SetWorldLocation(lines[0]->GetLocationAtTime(lines[0]->Duration * playerLineTime, ESplineCoordinateSpace::World));
@ -70,7 +71,7 @@ void ACrossyRoadManager::End()
PrimaryActorTick.SetTickFunctionEnable(false); PrimaryActorTick.SetTickFunctionEnable(false);
for(int32 handler : inputHandlers) for(int32 handler : inputHandlers)
player->inputComponent->RemoveBindingByHandle(handler); ACustomPlayerController::GetInput()->RemoveBindingByHandle(handler);
player->UnlockPlayer(FPlayerLock::All()); player->UnlockPlayer(FPlayerLock::All());
player->ReturnPlayerView(); player->ReturnPlayerView();

View File

@ -6,13 +6,14 @@
#include "EnhancedInputComponent.h" #include "EnhancedInputComponent.h"
#include "InputMappingContext.h" #include "InputMappingContext.h"
#include "CustomPlayerController.h"
#include "MainGameModeBase.h" #include "MainGameModeBase.h"
#include "PlayerBase.h" #include "PlayerBase.h"
AFishingManager::AFishingManager() AFishingManager::AFishingManager()
{ {
static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/Minigame/IMC_Minigame_Fishing.IMC_Minigame_Fishing'") }; static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/Minigame/IMC_Minigame_Fishing.IMC_Minigame_Fishing'") };
input = asset.Object; context = asset.Object;
} }
void AFishingManager::Start(APlayerBase* playerPawn, FMinigameEndCallback delegate) void AFishingManager::Start(APlayerBase* playerPawn, FMinigameEndCallback delegate)
@ -24,15 +25,17 @@ void AFishingManager::Start(APlayerBase* playerPawn, FMinigameEndCallback delega
player->LockPlayer(FPlayerLock::All()); player->LockPlayer(FPlayerLock::All());
auto& mapping = input.LoadSynchronous()->GetMapping(0); auto input = ACustomPlayerController::GetInput();
handler1 = player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Started, this, &AFishingManager::OnInputHold).GetHandle(); auto& mapping = context.LoadSynchronous()->GetMapping(0);
handler2 = player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Completed, this, &AFishingManager::OnInputUnhold).GetHandle(); handler1 = input->BindAction(mapping.Action, ETriggerEvent::Started, this, &AFishingManager::OnInputHold).GetHandle();
handler2 = input->BindAction(mapping.Action, ETriggerEvent::Completed, this, &AFishingManager::OnInputUnhold).GetHandle();
} }
void AFishingManager::End() void AFishingManager::End()
{ {
player->inputComponent->RemoveBindingByHandle(handler1); auto input = ACustomPlayerController::GetInput();
player->inputComponent->RemoveBindingByHandle(handler2); input->RemoveBindingByHandle(handler1);
input->RemoveBindingByHandle(handler2);
player->UnlockPlayer(FPlayerLock::All()); player->UnlockPlayer(FPlayerLock::All());

View File

@ -27,7 +27,7 @@ void AMinigame::Restart()
UInputMappingContext* AMinigame::GetInputMappings() UInputMappingContext* AMinigame::GetInputMappings()
{ {
return input.LoadSynchronous(); return context.LoadSynchronous();
} }
void AMinigame::Start(APlayerBase* playerPawn, FMinigameEndCallback delegate) void AMinigame::Start(APlayerBase* playerPawn, FMinigameEndCallback delegate)
@ -35,10 +35,10 @@ void AMinigame::Start(APlayerBase* playerPawn, FMinigameEndCallback delegate)
player = playerPawn; player = playerPawn;
callback = delegate; callback = delegate;
if(input) if(context)
if(auto PC = Cast<APlayerController>(playerPawn->GetController())) if(auto PC = Cast<APlayerController>(playerPawn->GetController()))
if(auto inputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer())) if(auto inputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer()))
inputSubsystem->AddMappingContext(input.LoadSynchronous(), 0); inputSubsystem->AddMappingContext(context.LoadSynchronous(), 0);
OnStart(); OnStart();
} }

View File

@ -55,6 +55,6 @@ protected:
bool ended = false; bool ended = false;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
TSoftObjectPtr<class UInputMappingContext> input = nullptr; TSoftObjectPtr<class UInputMappingContext> context = nullptr;
}; };

View File

@ -9,7 +9,7 @@
#include "EnhancedInputComponent.h" #include "EnhancedInputComponent.h"
#include "InputMappingContext.h" #include "InputMappingContext.h"
#include "CustomGameInstanceBase.h" #include "CustomPlayerController.h"
#include "MainGameModeBase.h" #include "MainGameModeBase.h"
#include "PlayerBase.h" #include "PlayerBase.h"
#include "SubwaySurfObstacle.h" #include "SubwaySurfObstacle.h"
@ -19,7 +19,7 @@ ASubwaySurfManager::ASubwaySurfManager()
: AMinigame() : AMinigame()
{ {
static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/Minigame/IMC_Minigame_SubwaySurf.IMC_Minigame_SubwaySurf'") }; static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/Minigame/IMC_Minigame_SubwaySurf.IMC_Minigame_SubwaySurf'") };
input = asset.Object; context = asset.Object;
auto root = CreateDefaultSubobject<USceneComponent>(TEXT("Scene")); auto root = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
@ -43,16 +43,17 @@ void ASubwaySurfManager::Start(APlayerBase* playerPawn, FMinigameEndCallback del
player->LockPlayer(FPlayerLock::All()); player->LockPlayer(FPlayerLock::All());
player->SwitchToView(this); player->SwitchToView(this);
for(auto& mapping : input.LoadSynchronous()->GetMappings()) auto input = ACustomPlayerController::GetInput();
for(auto& mapping : context.LoadSynchronous()->GetMappings())
{ {
if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Up")))) if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Up"))))
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ASubwaySurfManager::Up).GetHandle()); inputHandlers.Add(input->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ASubwaySurfManager::Up).GetHandle());
else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Down")))) else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Down"))))
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ASubwaySurfManager::Down).GetHandle()); inputHandlers.Add(input->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ASubwaySurfManager::Down).GetHandle());
else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Left")))) else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Left"))))
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ASubwaySurfManager::Left).GetHandle()); inputHandlers.Add(input->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ASubwaySurfManager::Left).GetHandle());
else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Right")))) else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Right"))))
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ASubwaySurfManager::Right).GetHandle()); inputHandlers.Add(input->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ASubwaySurfManager::Right).GetHandle());
} }
playerPos->SetRelativeLocation(lines[1]->GetLocationAtTime(lines[1]->Duration * 0.01f, ESplineCoordinateSpace::Local)); playerPos->SetRelativeLocation(lines[1]->GetLocationAtTime(lines[1]->Duration * 0.01f, ESplineCoordinateSpace::Local));
@ -66,7 +67,7 @@ void ASubwaySurfManager::End()
PrimaryActorTick.SetTickFunctionEnable(false); PrimaryActorTick.SetTickFunctionEnable(false);
for(int32 handler : inputHandlers) for(int32 handler : inputHandlers)
player->inputComponent->RemoveBindingByHandle(handler); ACustomPlayerController::GetInput()->RemoveBindingByHandle(handler);
player->UnlockPlayer(FPlayerLock::All()); player->UnlockPlayer(FPlayerLock::All());
player->ReturnPlayerView(); player->ReturnPlayerView();

View File

@ -4,16 +4,14 @@
#include "PlayerBase.h" #include "PlayerBase.h"
#include "Camera/CameraComponent.h" #include "Camera/CameraComponent.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "GameFramework/CharacterMovementComponent.h" #include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/SpringArmComponent.h" #include "GameFramework/SpringArmComponent.h"
#include "InputMappingContext.h" #include "InputMappingContext.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "Kismet/KismetMathLibrary.h" #include "Kismet/KismetMathLibrary.h"
#include "CustomGameInstanceBase.h"
#include "CustomGameUserSettings.h" #include "CustomGameUserSettings.h"
#include "CustomPlayerController.h"
#include "Interactable/Activators/InteractableActivator.h" #include "Interactable/Activators/InteractableActivator.h"
#include "Interactable/Interactable.h" #include "Interactable/Interactable.h"
#include "Interactable/Modificators/InteractableModificator.h" #include "Interactable/Modificators/InteractableModificator.h"
@ -84,44 +82,9 @@ void APlayerBase::BeginPlay()
camera->PostProcessSettings.MotionBlurAmount = gameSettings->bUseMotionBlur ? 1.0f : 0.0f; camera->PostProcessSettings.MotionBlurAmount = gameSettings->bUseMotionBlur ? 1.0f : 0.0f;
} }
playerController = Cast<APlayerController>(GetController());
if(playerController)
{
if(auto inputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(playerController->GetLocalPlayer()))
{
if(auto GI = UCustomGameInstanceBase::GetGameInstance())
{
inputSubsystem->ClearAllMappings();
for(auto& inputContext : GI->inputContexts)
{
inputSubsystem->AddMappingContext(inputContext.LoadSynchronous(), 0);
}
}
}
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;
@ -257,12 +220,8 @@ void APlayerBase::UpdatePitch(float min, float max)
void APlayerBase::LoadInteractablesActivators() void APlayerBase::LoadInteractablesActivators()
{ {
auto GI = UCustomGameInstanceBase::GetGameInstance();
if(!GI)
return;
TSet<UClass*> instancedActivators; TSet<UClass*> instancedActivators;
for(auto& act : GI->interactionsActivators) for(auto& act : AInteractable::interactionActivators)
{ {
if(instancedActivators.Contains(act)) if(instancedActivators.Contains(act))
continue; continue;

View File

@ -8,8 +8,6 @@
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)
@ -66,20 +64,12 @@ public:
FPlayerMovedDelegate OnPlayerMoved; FPlayerMovedDelegate OnPlayerMoved;
FVector moveVector; FVector moveVector;
FPlayerAnyKeyPressedDelegate onAnyKeyPressedDelegate;
FPlayerAnyKeyReleasedDelegate onAnyKeyReleasedDelegate;
class UEnhancedInputComponent* inputComponent = nullptr;
class AActor* leftPocketItem = nullptr; class AActor* leftPocketItem = nullptr;
class AActor* rightPocketItem = nullptr; class AActor* rightPocketItem = nullptr;
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();

View File

@ -6,6 +6,7 @@
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "CommonFunctions.h" #include "CommonFunctions.h"
#include "CustomPlayerController.h"
#include "MainGameModeBase.h" #include "MainGameModeBase.h"
#include "PlayerBase.h" #include "PlayerBase.h"
#include "Widgets/WidgetsManager.h" #include "Widgets/WidgetsManager.h"
@ -84,10 +85,10 @@ void UQuickTimeEventManager::OnEventEnd(int32 id, EQuickTimeEventResult result)
if(_events.IsEmpty()) if(_events.IsEmpty())
{ {
if(auto player = UCommonFunctions::GetPlayer(this)) if(auto PC = ACustomPlayerController::Get())
{ {
player->onAnyKeyPressedDelegate.RemoveDynamic(this, &UQuickTimeEventManager::OnInputPressed); PC->onAnyKeyPressed.RemoveDynamic(this, &UQuickTimeEventManager::OnInputPressed);
player->onAnyKeyReleasedDelegate.RemoveDynamic(this, &UQuickTimeEventManager::OnInputReleased); PC->onAnyKeyReleased.RemoveDynamic(this, &UQuickTimeEventManager::OnInputReleased);
} }
UCommonFunctions::ExitSlowMotion(); UCommonFunctions::ExitSlowMotion();
} }
@ -153,12 +154,12 @@ void UQuickTimeEventManager::OnFirstEventInit()
{ {
if(_events.IsEmpty()) if(_events.IsEmpty())
{ {
if(auto player = UCommonFunctions::GetPlayer(this)) if(auto PC = ACustomPlayerController::Get())
{ {
GetWorld()->GetTimerManager().SetTimerForNextTick([manager = this, player = player]() GetWorld()->GetTimerManager().SetTimerForNextTick([=, this]()
{ {
player->onAnyKeyPressedDelegate.AddDynamic(manager, &UQuickTimeEventManager::OnInputPressed); PC->onAnyKeyPressed.AddDynamic(this, &UQuickTimeEventManager::OnInputPressed);
player->onAnyKeyReleasedDelegate.AddDynamic(manager, &UQuickTimeEventManager::OnInputReleased); PC->onAnyKeyReleased.AddDynamic(this, &UQuickTimeEventManager::OnInputReleased);
}); });
} }
UCommonFunctions::EnterSlowMotion(); UCommonFunctions::EnterSlowMotion();
@ -168,12 +169,12 @@ void UQuickTimeEventManager::OnFirstEventInit()
void UQuickTimeEventManager::CreateEvent(FQuickTimeEventEnqueProperties& properties, bool sequence) void UQuickTimeEventManager::CreateEvent(FQuickTimeEventEnqueProperties& properties, bool sequence)
{ {
Event event{ properties.type, properties.key, properties.callback, sequence }; Event event{ properties.type, properties.key, properties.callback, sequence };
GetWorld()->GetTimerManager().SetTimer(event.timer, [id = event.GetId(), manager = this]() GetWorld()->GetTimerManager().SetTimer(event.timer, [id = event.GetId(), this]()
{ {
EQuickTimeEventResult result = EQuickTimeEventResult::FailedTime; EQuickTimeEventResult result = EQuickTimeEventResult::FailedTime;
if(auto WM = AMainGameModeBase::GetWidgetsManager()) if(auto WM = AMainGameModeBase::GetWidgetsManager())
result = WM->RemoveQuickTimeEvent(id); result = WM->RemoveQuickTimeEvent(id);
manager->OnEventEnd(id, result); this->OnEventEnd(id, result);
}, properties.duration, false); }, properties.duration, false);
_events.Add(event.GetId(), event); _events.Add(event.GetId(), event);

View File

@ -23,10 +23,10 @@ void UInteractableHintWidgetManager::Append(const UInteractableModificator* modi
return; return;
} }
if(hintsMap.Contains(modificator) || !modificator->GetMappingContext()) if(hintsMap.Contains(modificator) || !modificator->GetMappingContext().IsValid())
return; return;
const auto& mappings = modificator->GetMappingContext()->GetMappings(); const auto& mappings = modificator->GetMappingContext().LoadSynchronous()->GetMappings();
for(int32 i = hints->GetChildrenCount() - count - mappings.Num(); i < 0; ++i) for(int32 i = hints->GetChildrenCount() - count - mappings.Num(); i < 0; ++i)
{ {

View File

@ -5,7 +5,7 @@
#include "Animation/WidgetAnimation.h" #include "Animation/WidgetAnimation.h"
#include "CustomGameInstanceBase.h" #include "CustomGameInstance.h"
#include "MainGameModeBase.h" #include "MainGameModeBase.h"
#include "MainMenuButtonWidget.h" #include "MainMenuButtonWidget.h"
#include "Widgets/WidgetsManager.h" #include "Widgets/WidgetsManager.h"
@ -14,7 +14,7 @@ bool UMainMenuWidget::Initialize()
{ {
if(ButtonLoadLastSave) if(ButtonLoadLastSave)
{ {
auto GI = UCustomGameInstanceBase::GetGameInstance(); auto GI = UCustomGameInstance::GetGameInstance();
if(GI && GI->saveData) if(GI && GI->saveData)
{ {
ButtonLoadLastSave->SetIsEnabled(true); ButtonLoadLastSave->SetIsEnabled(true);

View File

@ -10,7 +10,7 @@
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "UObject/ScriptInterface.h" #include "UObject/ScriptInterface.h"
#include "CustomGameInstanceBase.h" #include "CustomGameInstance.h"
#include "Interactable/Interactable.h" #include "Interactable/Interactable.h"
#include "Interactable/Modificators/InteractableModificator.h" #include "Interactable/Modificators/InteractableModificator.h"
#include "Interactable/Modificators/InventoryInteractableModificator.h" #include "Interactable/Modificators/InventoryInteractableModificator.h"