Refactor of interactable stuff, use the plugin and new interface for this, tweaks to SSGI shader so it's usable in game

This commit is contained in:
2026-09-03 23:40:00 +02:00
parent c13ad6c99f
commit 7327c7f98a
66 changed files with 229 additions and 186 deletions

View File

@@ -194,3 +194,7 @@ CameraZoomLevels=(((TagName="Camera.BoomOffset.Default"), (X=-1200.000000,Y=0.00
ExpIncreaseEffectClass=/Script/Engine.BlueprintGeneratedClass'/Game/Blueprints/GameEffects/GSE_AddExp_Template.GSE_AddExp_Template_C'
GlobalSettingsDataSheet=/Game/GameData/CSV/GlobalKeyValueSettings.GlobalKeyValueSettings
[/Script/InteractionSystem.InteractionSettings]
DefaultInteractionWidgetClass=/Script/UMG.WidgetBlueprintGeneratedClass'/Game/UI/InteractionUI/WBP_Eleri_Interaction.WBP_Eleri_Interaction_C'
InteractableMaxDistance=500.000000

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -7,7 +7,6 @@
#include "Kismet/KismetMathLibrary.h"
#include "Kismet/GameplayStatics.h"
#include "EnhancedInputSubsystems.h"
#include "Interface/ZoneInteractableInterface.h"
#include "../GameObjects/RemovableStaticMeshActor.h"
#include "../Public/EleriPlayerController.h"
#include "../Public/MyCharacter.h"

View File

@@ -35,6 +35,9 @@ ABaseCharacter::ABaseCharacter()
PrimaryActorTick.bCanEverTick = true;
StateTreeComponent = CreateDefaultSubobject<UStateTreeAIComponent>("State Tree Component");
StateTreeComponent->SetStartLogicAutomatically(false);
WidgetComponent = CreateDefaultSubobject<UInteractionWidgetComponent>(TEXT("WidgetComponent"));
WidgetComponent->SetupAttachment(RootComponent);
}
// Called when the game starts or when spawned
@@ -113,9 +116,19 @@ void ABaseCharacter::ChangeFaceAnimation(EDialogueEmotion Emotion)
CurrentFaceFrameIndex = 0;
}
void ABaseCharacter::Interact_Implementation()
void ABaseCharacter::ToggleInteractableUI_Implementation(bool bActive)
{
IZoneInteractableInterface::Interact_Implementation();
if (bActive && !IInteractableActorInterface::Execute_IsInteractable(this))
{
return;
}
IInteractableActorInterface::ToggleInteractableUI_Implementation(bActive);
if (WidgetComponent)
{
WidgetComponent->ToggleWidget(bActive);
}
}
// Called every frame

View File

@@ -3,8 +3,9 @@
#pragma once
#include "CoreMinimal.h"
#include "Components/InteractionWidgetComponent.h"
#include "GameFramework/Pawn.h"
#include "ProjectEleri/Public/Interface/ZoneInteractableInterface.h"
#include "Interface/InteractableActorInterface.h"
#include "ProjectEleri/Public/Interface/NpcSpeakerDataInterface.h"
#include "ProjectEleri/Data/FaceExpressionDataAsset.h"
#include "StateTreeModule/Public/StateTree.h"
@@ -18,7 +19,7 @@ class UCapsuleComponent;
class USkeletalMeshComponent;
UCLASS(BlueprintType)
class PROJECTELERI_API ABaseCharacter : public APawn, public IZoneInteractableInterface, public INpcSpeakerDataInterface
class PROJECTELERI_API ABaseCharacter : public APawn, public IInteractableActorInterface, public INpcSpeakerDataInterface
{
GENERATED_BODY()
@@ -39,8 +40,7 @@ public:
UFUNCTION(BlueprintCallable, BlueprintPure)
UCapsuleComponent* GetCapsuleComponent() { return Capsule; }
virtual FText GetInteractionText_Implementation() override { return FText::FromString("Talk"); }
virtual void Interact_Implementation() override;
virtual void ToggleInteractableUI_Implementation(bool bActive) override;
protected:
UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
@@ -62,6 +62,9 @@ protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Movement")
UExtendedPawnMovement* MovementComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UInteractionWidgetComponent* WidgetComponent;
// Called when the game starts or when spawned
virtual void BeginPlay() override;

View File

@@ -10,6 +10,12 @@ AEleriBaseActor::AEleriBaseActor()
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
PersistentId = FGuid::NewGuid();
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
SetRootComponent(RootComponent);
WidgetComponent = CreateDefaultSubobject<UInteractionWidgetComponent>(TEXT("WidgetComponent"));
WidgetComponent->SetupAttachment(RootComponent);
}
// Called when the game starts or when spawned
@@ -69,6 +75,21 @@ void AEleriBaseActor::RequestLoad(FActorSaveData& Data)
ISaveableObjectInterface::Execute_OnDataLoaded(this);
}
void AEleriBaseActor::ToggleInteractableUI_Implementation(bool bActive)
{
if (bActive && !IInteractableActorInterface::Execute_IsInteractable(this))
{
return;
}
IInteractableActorInterface::ToggleInteractableUI_Implementation(bActive);
if (WidgetComponent)
{
WidgetComponent->ToggleWidget(bActive);
}
}
void AEleriBaseActor::OnDataLoaded_Implementation() {}

View File

@@ -7,6 +7,8 @@
#include "ProjectEleri/Public/Interface/SaveableObjectInterface.h"
#include "ProjectEleri/Public/Interface/ActorPersistentIdInterface.h"
#include "GameplayTagContainer.h"
#include "Components/InteractionWidgetComponent.h"
#include "Interface/InteractableActorInterface.h"
#include "EleriBaseActor.generated.h"
@@ -14,7 +16,8 @@ UCLASS()
class PROJECTELERI_API AEleriBaseActor :
public AActor,
public ISaveableObjectInterface,
public IActorPersistentIdInterface
public IActorPersistentIdInterface,
public IInteractableActorInterface
{
GENERATED_BODY()
@@ -29,6 +32,8 @@ public:
virtual void RequestLoad(FActorSaveData &Data) override;
virtual FGuid GetPersistentId() const override { return PersistentId; }
virtual void ToggleInteractableUI_Implementation(bool bActive) override;
protected:
virtual void OnDataLoaded_Implementation() override;
@@ -43,6 +48,9 @@ protected:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "ID")
FGuid PersistentId;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UInteractionWidgetComponent* WidgetComponent;
UFUNCTION(BlueprintCallable, Category = "Saveable Tag Data", meta = (GameplayTagFilter = "SaveGameTags"))
void SetSaveableTagData(FGameplayTag Tag, int32 NewValue);

View File

@@ -13,6 +13,12 @@
ARemovableStaticMeshActor::ARemovableStaticMeshActor()
{
PrimaryActorTick.bCanEverTick = true;
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
SetRootComponent(RootComponent);
WidgetComponent = CreateDefaultSubobject<UInteractionWidgetComponent>(TEXT("WidgetComponent"));
WidgetComponent->SetupAttachment(RootComponent);
}
void ARemovableStaticMeshActor::BeginPlay()
@@ -29,6 +35,26 @@ void ARemovableStaticMeshActor::BeginPlay()
CurrentMemorizedTransform = GetActorTransform();
}
void ARemovableStaticMeshActor::ToggleInteractableUI_Implementation(bool bActive)
{
if (bActive && !IInteractableActorInterface::Execute_IsInteractable(this))
{
return;
}
IInteractableActorInterface::ToggleInteractableUI_Implementation(bActive);
if (WidgetComponent)
{
WidgetComponent->ToggleWidget(bActive);
}
}
bool ARemovableStaticMeshActor::IsInteractable_Implementation() const
{
return true;
}
void ARemovableStaticMeshActor::BindToItem(UInventoryComponent* InInventory, FItemStack InItemStack)
{
InventoryRef = InInventory;

View File

@@ -5,6 +5,8 @@
#include "CoreMinimal.h"
#include "Engine/StaticMeshActor.h"
#include "../Public/InventoryComponent.h"
#include "Components/InteractionWidgetComponent.h"
#include "Interface/InteractableActorInterface.h"
#include "RemovableStaticMeshActor.generated.h"
@@ -17,7 +19,7 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnPickup);
*
*/
UCLASS(BlueprintType)
class PROJECTELERI_API ARemovableStaticMeshActor : public AStaticMeshActor
class PROJECTELERI_API ARemovableStaticMeshActor : public AStaticMeshActor, public IInteractableActorInterface
{
GENERATED_BODY()
@@ -26,6 +28,9 @@ public:
ARemovableStaticMeshActor();
virtual void BeginPlay() override;
virtual void ToggleInteractableUI_Implementation(bool bActive) override;
virtual bool IsInteractable_Implementation() const override;
UPROPERTY()
bool bFromInventory;
@@ -84,6 +89,9 @@ public:
FOnPlaced OnPlaced;
UPROPERTY(BlueprintAssignable, EditAnywhere, BLueprintReadWrite)
FOnPickup OnPickup;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UInteractionWidgetComponent* WidgetComponent;
//Used when placing stuff from inventory so we can return it to inventory
//if we cancel placing item
@@ -106,4 +114,6 @@ public:
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void K2_TogglePlaceableEffects(bool bIsPlaceable);
};

View File

@@ -2,15 +2,12 @@
#include "EleriPlayerController.h"
#include "EnhancedInputComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "GameFramework/Character.h"
#include "EnhancedInputSubsystems.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Interface/ZoneInteractableInterface.h"
#include "ProjectEleri/System/MainBlueprintFunctionLibrary.h"
#include "ProjectEleri/Components/MoveActorsComponent.h"
#include "../GameObjects/RemovableStaticMeshActor.h"
#include "Components/WidgetComponent.h"
#include "Kismet/GameplayStatics.h"
#include "BookOfAlchemyManager.h"
#include "AlchemyManager.h"
@@ -76,7 +73,7 @@ void AEleriPlayerController::Tick(float DeltaTime)
{
for (int32 i = 0; i < ActorsOverlappingWith.Num(); i++)
{
if (!ActorsOverlappingWith[i]->Implements<UZoneInteractableInterface>() || !IZoneInteractableInterface::Execute_IsInteractable(ActorsOverlappingWith[i]))
if (!ActorsOverlappingWith[i]->Implements<UInteractableActorInterface>() || !IInteractableActorInterface::Execute_IsInteractable(ActorsOverlappingWith[i]))
{
RemoveInteractableObject(ActorsOverlappingWith[i]);
i--;
@@ -680,16 +677,15 @@ void AEleriPlayerController::OnToggleGridAction(const FInputActionValue &Value)
void AEleriPlayerController::AddInteractableObject(UObject *ObjectToAdd)
{
if (IsValid(ObjectToAdd) && ObjectToAdd->Implements<UZoneInteractableInterface>() && IZoneInteractableInterface::Execute_IsInteractable(ObjectToAdd))
if (IsValid(ObjectToAdd) && ObjectToAdd->Implements<UInteractableActorInterface>() && IInteractableActorInterface::Execute_IsInteractable(ObjectToAdd))
{
FText InteractableText = IZoneInteractableInterface::Execute_GetInteractionText(ObjectToAdd);
FText InteractableText = IInteractableActorInterface::Execute_GetInteractionText(ObjectToAdd);
if (UMainGameWidget *MainWidget = UMainBlueprintFunctionLibrary::GetMainGameWidget(this))
{
if (UInteractionWidget *InteractionWidget = MainWidget->GetInteractionWidget())
{
InteractionWidget->PushInteractableObject(ObjectToAdd, InteractableText);
}
IZoneInteractableInterface::Execute_PlayerEntered(ObjectToAdd, true);
}
ActorsOverlappingWith.Add(ObjectToAdd);
}
@@ -708,9 +704,9 @@ void AEleriPlayerController::RemoveInteractableObject(UObject *ObjectToAdd)
if (IsPaused())
return;
if (IsValid(ObjectToAdd) && ObjectToAdd->Implements<UZoneInteractableInterface>())
if (IsValid(ObjectToAdd) && ObjectToAdd->Implements<UInteractableActorInterface>())
{
FText InteractableText = IZoneInteractableInterface::Execute_GetInteractionText(ObjectToAdd);
FText InteractableText = IInteractableActorInterface::Execute_GetInteractionText(ObjectToAdd);
if (UMainGameWidget *MainWidget = UMainBlueprintFunctionLibrary::GetMainGameWidget(this))
{
if (UInteractionWidget *InteractionWidget = MainWidget->GetInteractionWidget())
@@ -718,7 +714,6 @@ void AEleriPlayerController::RemoveInteractableObject(UObject *ObjectToAdd)
InteractionWidget->PopInteractableObject(ObjectToAdd);
}
}
IZoneInteractableInterface::Execute_PlayerEntered(ObjectToAdd, false);
}
ActorsOverlappingWith.Remove(ObjectToAdd);
if (SelectedInteractable == ObjectToAdd)
@@ -756,14 +751,7 @@ void AEleriPlayerController::ToggleInteractionMenu(bool bActive)
void AEleriPlayerController::OnInteractionMenuSelectAction(const FInputActionValue &Value)
{
if (SelectedInteractable)
{
IZoneInteractableInterface::Execute_Interact(SelectedInteractable);
if (!IZoneInteractableInterface::Execute_KeepInteractionMenuOpenWhenSelected(SelectedInteractable))
{
ToggleInteractionMenu(false);
}
}
}
void AEleriPlayerController::OnInteractionMenuUpAction(const FInputActionValue &Value)

View File

@@ -1,7 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Interface/ZoneInteractableInterface.h"
// Add default functionality here for any IZoneInteractableIntereface functions that are not pure virtual.

View File

@@ -4,20 +4,14 @@
#include "MyCharacter.h"
#include "EleriPlayerController.h"
#include "Kismet/GameplayStatics.h"
#include "Interface/ZoneInteractableInterface.h"
#include "EleriSaveGame.h"
#include "EleriGameInstance.h"
#include "PaperFlipbookComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "../GameObjects/WaterBall.h"
#include "ProjectEleri/GameObjects/BookActor.h"
#include "TimeOfDayManager.h"
#include "Components/PostProcessComponent.h"
#include "GameFramework/PawnMovementComponent.h"
#include "ProjectEleri/GameObjects/BenchmarkActor.h"
#include "ProjectEleri/System/MainBlueprintFunctionLibrary.h"
#include "ProjectEleri/UI/InteractionWidget.h"
#include "ProjectEleri/GameObjects/BookActor.h"
#include "ProjectEleri/GameObjects/BroomActor.h"
#include "Components/CapsuleComponent.h"
#include "Components/StatForgeComponent.h"

View File

@@ -56,6 +56,9 @@ ATimeOfDayManager::ATimeOfDayManager()
WeatherPresetDistributionMap.GetKeys(Keys);
CurrentWeatherPreset = Keys[0];
}
WidgetComponent = CreateDefaultSubobject<UInteractionWidgetComponent>(TEXT("WidgetComponent"));
WidgetComponent->SetupAttachment(RootComponent);
}
// Called when the game starts or when spawned
@@ -566,6 +569,21 @@ void ATimeOfDayManager::LoadSaveData(const FTimeOfDaySaveData &saveData)
QueuedWeatherPreset = Cast<UWeatherPresetDataAsset>(saveData.CurrentWeatherSoftObjectPath.TryLoad());
}
void ATimeOfDayManager::ToggleInteractableUI_Implementation(bool bActive)
{
if (bActive && !IInteractableActorInterface::Execute_IsInteractable(this))
{
return;
}
IInteractableActorInterface::ToggleInteractableUI_Implementation(bActive);
if (WidgetComponent)
{
WidgetComponent->ToggleWidget(bActive);
}
}
int32 ATimeOfDayManager::GetWeatherDistributionMaxValue() const
{
float Value = 0;

View File

@@ -1,44 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "ZoneInteractableInterface.generated.h"
// This class does not need to be modified.
UINTERFACE(MinimalAPI, Blueprintable)
class UZoneInteractableInterface : public UInterface
{
GENERATED_BODY()
};
/**
*
*/
class PROJECTELERI_API IZoneInteractableInterface
{
GENERATED_BODY()
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
/**A version of React To Trigger that can be implemented in C++ or Blueprint. */
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void Interact();
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
bool IsInteractable();
virtual bool IsInteractable_Implementation() { return true; }
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
bool KeepInteractionMenuOpenWhenSelected();
virtual bool KeepInteractionMenuOpenWhenSelected_Implementation() { return false; }
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
FText GetInteractionText();
virtual FText GetInteractionText_Implementation() { return FText(); }
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void PlayerEntered(bool bIsPlayerInside);
};

View File

@@ -15,8 +15,10 @@
#include "UObject/NameTypes.h"
#include "../Items/ItemDatabase.h"
#include "GameplayTagContainer.h"
#include "Components/InteractionWidgetComponent.h"
#include "Components/VolumetricCloudComponent.h"
#include "Engine/ExponentialHeightFog.h"
#include "Interface/InteractableActorInterface.h"
#include "ProjectEleri/GameEventSystem/GameEventDataAsset.h"
#include "ProjectEleri/System/TimeOfDayStruct.h"
@@ -103,7 +105,7 @@ public:
};
UCLASS()
class PROJECTELERI_API ATimeOfDayManager : public AActor
class PROJECTELERI_API ATimeOfDayManager : public AActor, public IInteractableActorInterface
{
GENERATED_BODY()
@@ -322,6 +324,8 @@ public:
FTimeOfDaySaveData GetSaveData() const;
void LoadSaveData(const FTimeOfDaySaveData &saveData);
virtual void ToggleInteractableUI_Implementation(bool bActive) override;
protected:
// Called when the game starts or when spawned
@@ -359,6 +363,9 @@ protected:
TMap<UWeatherPresetDataAsset *, float> WeatherPresetDistributionMap;
UPROPERTY()
UMaterialInstanceDynamic* VolumetricCloudMaterialInstance;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UInteractionWidgetComponent* WidgetComponent;
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)