Interactable code cleanup, complete activators

This commit is contained in:
Oleg Petruny 2024-06-02 11:39:07 +02:00
parent 2a5677656c
commit 15244e3936
54 changed files with 447 additions and 253 deletions

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

@ -1,6 +1,6 @@
{
"FileVersion": 3,
"EngineAssociation": "{0DD41C75-443A-77B1-7C02-5F9B73D04B7B}",
"EngineAssociation": "5.4",
"Category": "",
"Description": "",
"Modules": [

View File

@ -10,14 +10,14 @@ RWBuffer<unsigned int> Output;
void InteractableScreenCapturerBitMapCS(
uint3 dti : SV_DispatchThreadID)
{
switch (Input[dti.x])
{
case 0xFF00FFFF:
//Output[dti.x / 4] = Output[dti.x / 4] | (0xFF << 8 * (3 - (dti.x % 4))); // sets n-th byte to 0xFF
break;
default:
//Output[dti.x / 4] = Output[dti.x / 4] & ~(0xFF << 8 * (3 - (dti.x % 4))); // sets n-th byte to 0x00
break;
}
//Output[0] = 1;
Output[dti.x] = Input[dti.x];
//switch (Input[dti.x])
//{
// case 0xFF00FFFF:
// Output[dti.x / 4] = Output[dti.x / 4] | (0xFF << 8 * (3 - (dti.x % 4))); // sets n-th byte to 0xFF
// break;
// default:
// Output[dti.x / 4] = Output[dti.x / 4] & ~(0xFF << 8 * (3 - (dti.x % 4))); // sets n-th byte to 0x00
// break;
//}
}

View File

@ -7,13 +7,14 @@
#include "InputMappingContext.h"
#include "CustomGameUserSettings.h"
#include "Interactable/SawInteractable.h"
#include "Interactable/UsableInteractable.h"
#include "Interactable/Activators/InCameraInteractableActivator.h"
#include "Interactable/Activators/RaycastInteractableActivator.h"
void UCustomGameInstanceBase::Init()
{
// IN FUTURE ASSIGN FROM CONTENT LOADER MEMBER
interactionsActivators = { {UUsableInteractable::StaticClass()}, {USawInteractable::StaticClass()} };
interactionsActivators.Add(URaycastInteractableActivator::StaticClass());
interactionsActivators.Add(UInCameraInteractableActivator::StaticClass());
UGameInstance::Init();

View File

@ -19,7 +19,7 @@ public:
void ApplyMouseSettings();
UPROPERTY(EditDefaultsOnly)
TArray<TSubclassOf<class UInteractableComponent>> interactionsActivators;
TArray<TSubclassOf<class UInteractableActivator>> interactionsActivators;
protected:
UPROPERTY(EditDefaultsOnly)

View File

@ -1,9 +1,8 @@
// Oleg Petruny proprietary.
#include "Interactable/InCameraInteractableActivator.h"
#include "InCameraInteractableActivator.h"
#include "Interactable.h"
#include "InteractableScreenCapturer.h"
UInCameraInteractableActivator::UInCameraInteractableActivator(const FObjectInitializer& ObjectInitializer)
@ -14,9 +13,13 @@ UInCameraInteractableActivator::UInCameraInteractableActivator(const FObjectInit
return;
}
activatorType = EActivatorType::Saw;
scanDistance = 7000;
_capturer = CreateDefaultSubobject<UInteractableScreenCapturer>(TEXT("UInCameraInteractableActivator_UInteractableScreenCapturer"));
_capturer->interactableInScreenDelegate.BindUObject(this, &UInCameraInteractableActivator::NewSeenInteractable_Implementation);
_capturer->SetupAttachment(this);
_capturer->scanDistance = scanDistance;
PrimaryComponentTick.bCanEverTick = true;
PrimaryComponentTick.bStartWithTickEnabled = false;
@ -44,7 +47,7 @@ void UInCameraInteractableActivator::Scan_Implementation()
_interactablesToActivate.Dequeue(interactable);
if(interactableActivatedDelegate.IsBound())
{
interactableActivatedDelegate.Execute(interactable);
interactableActivatedDelegate.Execute(interactable, activatorType);
}
}
}

View File

@ -5,10 +5,12 @@
#include "Components/SceneComponent.h"
#include "CoreMinimal.h"
#include "../Interactable.h"
#include "InteractableActivator.generated.h"
DECLARE_DELEGATE_OneParam(FInteractableActivated, class AInteractable*);
DECLARE_DELEGATE_OneParam(FInteractableDeactivated, class AInteractable*);
DECLARE_DELEGATE_TwoParams(FInteractableActivated, AInteractable*, EActivatorType);
DECLARE_DELEGATE_TwoParams(FInteractableDeactivated, AInteractable*, EActivatorType);
UCLASS(Abstract, Blueprintable, BlueprintType)
class UInteractableActivator : public USceneComponent
@ -27,10 +29,13 @@ protected:
inline void Scan();
inline virtual void Scan_Implementation() PURE_VIRTUAL(UInteractableActivator::Scan_Implementation, );
UPROPERTY(EditDefaultsOnly)
EActivatorType activatorType;
UPROPERTY(EditDefaultsOnly)
float scanDistance = 200;
class UWorld* world;
class APlayerBase* player;
enum ECollisionChannel collisionChannel;
ECollisionChannel collisionChannel;
};

View File

@ -7,16 +7,18 @@
#include "Engine/TextureRenderTarget2D.h"
#include "Kismet/GameplayStatics.h"
#include "opencv2/imgproc.hpp"
#include "RenderGraphUtils.h"
#include "RHIGPUReadback.h"
#include "RHIResources.h"
#include "SceneView.h"
#include "TextureCompressorModule.h"
#include "Interactable.h"
#include "../Interactable.h"
#include "InteractableScreenCapturerBitMapCS.h"
constexpr float tickInterval = 1.0f / 5;
constexpr float textureWidth = 1280 / 2;
constexpr float textureHeight = 720 / 2;
constexpr float rayDistance = 7000;
UInteractableScreenCapturer::UInteractableScreenCapturer(const FObjectInitializer& ObjectInitializer)
: USceneCaptureComponent2D(ObjectInitializer)
@ -24,7 +26,8 @@ UInteractableScreenCapturer::UInteractableScreenCapturer(const FObjectInitialize
PrimaryComponentTick.bCanEverTick = false;
PrimaryComponentTick.bStartWithTickEnabled = false;
TextureTarget = LoadObject<UTextureRenderTarget2D>(this, TEXT("/Game/tempStaff/Input"));
TextureTarget = LoadObject<UTextureRenderTarget2D>(this, TEXT("/Game/Misc/Interactables/T_InteractableScreencapturerDebugInput"));
//_output = LoadObject<UTextureRenderTarget2D>(this, TEXT("/Game/Misc/Interactables/T_InteractableScreencapturerDebugOutput"));
//TextureTarget = ObjectInitializer.CreateDefaultSubobject<UTextureRenderTarget2D>(this, TEXT("UInteractableScreenCapturer_TextureRenderTarget"));
//TextureTarget->RenderTargetFormat = ETextureRenderTargetFormat::RTF_RGBA8;
//TextureTarget->ClearColor = FLinearColor::Black;
@ -36,12 +39,14 @@ UInteractableScreenCapturer::UInteractableScreenCapturer(const FObjectInitialize
PrimitiveRenderMode = ESceneCapturePrimitiveRenderMode::PRM_LegacySceneCapture;
bCaptureEveryFrame = 0;
bCaptureOnMovement = 0;
LODDistanceFactor = 10000;
LODDistanceFactor = 1;
bUseRayTracingIfEnabled = false;
CaptureSource = ESceneCaptureSource::SCS_BaseColor;
CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR;
CompositeMode = ESceneCaptureCompositeMode::SCCM_Overwrite;
PostProcessBlendWeight = 0;
PostProcessBlendWeight = 1;
auto ppMaterial = LoadObject<UMaterial>(this, TEXT("/Game/Misc/Interactables/M_InteractableScreencapturerPP"));
PostProcessSettings.AddBlendable(ppMaterial, 1.0f);
bUseCustomProjectionMatrix = false;
bAlwaysPersistRenderingState = true;
@ -57,6 +62,8 @@ UInteractableScreenCapturer::UInteractableScreenCapturer(const FObjectInitialize
ShowFlags.SetGame(true);
ShowFlags.SetMaterials(true);
ShowFlags.SetRendering(true);
ShowFlags.SetPostProcessMaterial(true);
ShowFlags.SetPostProcessing(true);
PrimaryComponentTick.TickInterval = tickInterval;
PrimaryComponentTick.bCanEverTick = true;
@ -74,7 +81,7 @@ void UInteractableScreenCapturer::TickComponent(float DeltaTime, enum ELevelTick
USceneCaptureComponent2D::TickComponent(DeltaTime, TickType, ThisTickFunction);
CaptureScene();
GetCameraView(DeltaTime, _view);
Process();
//Process();
}
break;
default:
@ -93,13 +100,71 @@ void UInteractableScreenCapturer::Process()
capture = TextureTarget->GetResource()->TextureRHI,
world = GetWorld(),
view = _view,
//output = _output->GetResource()->TextureRHI,
this
]
(FRHICommandListImmediate& RHICmdList)
{
#ifdef INTERACTABLE_ACTIVATOR_DEBUG
double StartTime = FPlatformTime::Seconds();
#endif // INTERACTABLE_ACTIVATOR_DEBUG
static FIntPoint _extent = capture->GetDesc().Extent;
static uint32 _size = _extent.X * _extent.Y;
static int32 _size = _extent.X * _extent.Y;
//FRHIResourceCreateInfo outBufferCreateInfo(TEXT("InteractableScreenCapturerCSOutBuffer"));
//EBufferUsageFlags outBufferUsage = EBufferUsageFlags::UnorderedAccess | EBufferUsageFlags::SourceCopy;
//FBufferRHIRef outBuffer = RHICmdList.CreateBuffer(_size * sizeof(uint32), outBufferUsage, 0, ERHIAccess::UAVCompute, outBufferCreateInfo);
//auto outBufferUAVCreateDesc = FRHIViewDesc::CreateBufferUAV()
// .SetType(FRHIViewDesc::EBufferType::Typed)
// .SetFormat(PF_R32_UINT)
// .SetNumElements(_size);
//auto outBufferUAV = RHICmdList.CreateUnorderedAccessView(outBuffer, outBufferUAVCreateDesc);
//
//TShaderMapRef<FInteractableScreenCapturerBitMapCS> shader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
//const uint32 threadsNum = FMath::DivideAndRoundUp(_size, FInteractableScreenCapturerBitMapCS::shader_threads_per_group_count);
//
//FInteractableScreenCapturerBitMapCS::FParameters shaderParams;
//shaderParams.Input = RHICmdList.CreateShaderResourceView(capture, FRHIViewDesc::CreateTextureSRV()
// .SetDimensionFromTexture(capture)
// .SetMipRange(0, 1));
//shaderParams.Output = outBufferUAV;
//
//FComputeShaderUtils::Dispatch(RHICmdList, shader, shaderParams, FIntVector(threadsNum, 1, 1));
//
//RHICmdList.Transition({ FRHITransitionInfo(outBufferUAV, ERHIAccess::UAVCompute, ERHIAccess::CopySrc) });
//
//// Kick off the readbacks.
//FRHIGPUBufferReadback outBufferReadback(TEXT("InteractableScreenCapturerCSOutBufferReadback"));
//outBufferReadback.EnqueueCopy(RHICmdList, outBuffer, _size * sizeof(uint32));
//
//// Sync the GPU. Unfortunately we can't use the fences because not all RHIs implement them yet.
//RHICmdList.BlockUntilGPUIdle();
//RHICmdList.FlushResources();
//
//uint32* outBufferData = (uint32*)outBufferReadback.Lock(_size * sizeof(uint32));
//uint32 sstride = 0;
//uint32* ddata = (uint32*)RHICmdList.LockTexture2D(
// output,
// 0,
// RLM_WriteOnly,
// sstride,
// false);
//for(int32 i = 0; i < _size; ++i)
//{
// ddata[i] = outBufferData[i];
// //switch(outBufferData[i])
// //{
// // case 0xFF:
// // ddata[i] = 0xFFFFFFFF;
// // default:
// // ddata[i] = 0x00000000;
// //}
//}
//RHICmdList.UnlockTexture2D(output, 0, false);
//
//outBufferReadback.Unlock();
static uint8* _bitMap = new uint8[_size]; // cv::Mat allocation is weird sometimes...
@ -110,7 +175,7 @@ void UInteractableScreenCapturer::Process()
RLM_ReadOnly,
stride,
false);
for(uint32 i = 0; i < _size; ++i)
for(int32 i = 0; i < _size; ++i)
{
switch(data[i].R)
{
@ -167,17 +232,15 @@ void UInteractableScreenCapturer::Process()
* (FInverseRotationMatrix(view.Rotation) * FMatrix(FPlane(0, 0, 1, 0), FPlane(1, 0, 0, 0), FPlane(0, 1, 0, 0), FPlane(0, 0, 0, 1)))
* view.CalculateProjectionMatrix())
.InverseFast();
GEngine->AddOnScreenDebugMessage(60, 0.5f, FColor::Yellow, FString::Printf(TEXT("x:%f, y:%f"), view.Rotation.Yaw, view.Rotation.Roll));
FVector worldLoc, worldDir;
for(int i = 1; i < components; ++i)
{
FVector2D screenPos = { ((double*)componentsCentroids.data)[i * 2], ((double*)componentsCentroids.data)[i * 2 + 1] };
FSceneView::DeprojectScreenToWorld(screenPos, FIntRect{ {0, 0}, _extent }, _invProjection, worldLoc, worldDir);
//GEngine->AddOnScreenDebugMessage(66 + i, 0.5f, FColor::Yellow, FString::Printf(TEXT("x:%f, y:%f"), screenPos.X, screenPos.Y));
FHitResult result{};
FVector startLocation = view.Location;
FVector endLocation = worldLoc + worldDir * rayDistance;
FVector endLocation = worldLoc + worldDir * scanDistance;
world->LineTraceSingleByChannel(
result,
startLocation,
@ -196,19 +259,23 @@ void UInteractableScreenCapturer::Process()
interactableInScreenDelegate.Execute(interactable);
});
}
//GEngine->AddOnScreenDebugMessage(10 + i, 0.5f, FColor::Yellow, interactable->GetName());
GEngine->AddOnScreenDebugMessage(20 + i, 0.5f, FColor::Yellow, FString::Printf(TEXT("dist:%f"), (view.Location - interactable->GetActorLocation()).Length()));
}
#ifdef INTERACTABLE_ACTIVATOR_DEBUG
DrawDebugLine(world, startLocation, endLocation, FColor::Green, false, tickInterval, 0, 0.5f);
#endif // INTERACTABLE_ACTIVATOR_DEBUG
}
#ifdef INTERACTABLE_ACTIVATOR_DEBUG
else
{
DrawDebugLine(world, startLocation, endLocation, FColor::Red, false, tickInterval, 10, 0.5f);
}
//DrawDebugLine(world, startLocation, endLocation, FColor::Red, false, tickInterval, 0, 0.5f);
#endif // INTERACTABLE_ACTIVATOR_DEBUG
}
GEngine->AddOnScreenDebugMessage(667, 0.5f, FColor::Yellow, FString::Printf(TEXT("time:%f"), FPlatformTime::Seconds() - StartTime));
#ifdef INTERACTABLE_ACTIVATOR_DEBUG
GEngine->AddOnScreenDebugMessage(30 + (int)EActivatorType::Saw, 0.5f, FColor::Yellow, FString::Printf(TEXT("ScreenCapturer calltime: %f"), FPlatformTime::Seconds() - StartTime));
#endif // INTERACTABLE_ACTIVATOR_DEBUG
running = false;
}
);

View File

@ -20,10 +20,14 @@ public:
FInteractableInScreen interactableInScreenDelegate;
UPROPERTY(EditAnywhere)
float scanDistance = 7000;
protected:
void Process();
private:
FMinimalViewInfo _view;
TSet<class AInteractable*> _sawInteractables;
//class UTextureRenderTarget2D* _output;
};

View File

@ -6,7 +6,11 @@
#include "DrawDebugHelpers.h"
#include "Engine/World.h"
#include "Interactable.h"
URaycastInteractableActivator::URaycastInteractableActivator(const FObjectInitializer& ObjectInitializer)
: UInteractableActivator(ObjectInitializer)
{
activatorType = EActivatorType::Use;
}
void URaycastInteractableActivator::Scan_Implementation()
{
@ -27,18 +31,25 @@ void URaycastInteractableActivator::Scan_Implementation()
{
if(_last != result.GetActor())
{
if(_last)
{
interactableDeactivatedDelegate.Execute(_last, activatorType);
_last = nullptr;
}
_activated = true;
if(auto interactable = Cast<AInteractable>(result.GetActor()))
{
_last = interactable;
if(interactableActivatedDelegate.IsBound())
{
interactableActivatedDelegate.Execute(interactable);
interactableActivatedDelegate.Execute(interactable, activatorType);
}
}
}
//DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Green, false, 0.5f, 0, 1.0f);
#ifdef INTERACTABLE_ACTIVATOR_DEBUG
DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Green, false, 0.5f, 0, 0.5f);
#endif // INTERACTABLE_ACTIVATOR_DEBUG
}
else
{
@ -46,12 +57,14 @@ void URaycastInteractableActivator::Scan_Implementation()
{
if(interactableDeactivatedDelegate.IsBound())
{
interactableDeactivatedDelegate.Execute(_last);
interactableDeactivatedDelegate.Execute(_last, activatorType);
}
_activated = false;
_last = nullptr;
}
//DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Red, false, 0.5f, 10, 1.0f);
#ifdef INTERACTABLE_ACTIVATOR_DEBUG
DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Red, false, 0.5f, 10, 0.5f);
#endif // INTERACTABLE_ACTIVATOR_DEBUG
}
}
}

View File

@ -12,6 +12,9 @@ class URaycastInteractableActivator : public UInteractableActivator
{
GENERATED_BODY()
public:
URaycastInteractableActivator(const FObjectInitializer& ObjectInitializer);
protected:
void Scan();
virtual void Scan_Implementation() override;

View File

@ -3,4 +3,59 @@
#include "Interactable.h"
#include "Kismet/GameplayStatics.h"
#include "../MainGameModeBase.h"
#include "../Widgets/WidgetsManager.h"
#include "Modificators/InteractableModificator.h"
void AInteractable::BeginPlay()
{
// FOR ADRESS TO COLOR
//if(auto m = material.LoadSynchronous())
//{
// if(material->VectorParameterValues.Num() > 0)
// {
// GEngine->AddOnScreenDebugMessage(5, 5.0f, FColor::Emerald, material->VectorParameterValues[0].ParameterInfo.Name.ToString());
// }
//}
TArray<UMeshComponent*> meshes;
GetComponents(meshes);
for(auto mesh : meshes)
{
mesh->CustomDepthStencilValue = 0;
mesh->CustomDepthStencilWriteMask = ERendererStencilMask::ERSM_Default;
mesh->SetRenderCustomDepth(true);
}
for(auto& modificatorClass : modificatorsClasses)
{
_modificators.Add(NewObject<UInteractableModificator>(this, modificatorClass));
}
}
void AInteractable::_Activate(EActivatorType type)
{
activated |= static_cast<uint8>(type);
if(auto WM = AMainGameModeBase::GetWidgetManager())
{
for(const auto modificator : _modificators)
{
WM->ShowInteractionHints(modificator);
}
}
Activate_Implementation(type);
}
void AInteractable::_Deactivate(EActivatorType type)
{
activated &= ~static_cast<uint8>(type);
if(auto WM = AMainGameModeBase::GetWidgetManager())
{
WM->HideInteractionHints(type);
}
Deactivate_Implementation(type);
}

View File

@ -4,19 +4,55 @@
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "UObject/ScriptInterface.h"
#include "Interactable.generated.h"
#define INTERACTABLE_DEBUG
//#define INTERACTABLE_ACTIVATOR_DEBUG
UENUM(BlueprintType, meta = (Bitflags))
enum class EActivatorType : uint8
{
None = 0,
Use = 1 << 0,
Saw = 1 << 1,
Custom1 = 1 << 2 UMETA(DisplayName = "Custom 1"),
Custom2 = 1 << 3 UMETA(DisplayName = "Custom 2"),
Custom3 = 1 << 4 UMETA(DisplayName = "Custom 3"),
Custom4 = 1 << 5 UMETA(DisplayName = "Custom 4"),
Custom5 = 1 << 6 UMETA(DisplayName = "Custom 5"),
Custom6 = 1 << 7 UMETA(DisplayName = "Custom 6")
};
ENUM_CLASS_FLAGS(EActivatorType)
UCLASS(Abstract, MinimalAPI, Blueprintable, BlueprintType)
class AInteractable : public AActor
{
GENERATED_BODY()
public:
void _Activate(EActivatorType type);
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
TArray<TSubclassOf<class UInteractableComponent>> GetInteractableComponents();
virtual TArray<TSubclassOf<class UInteractableComponent>> GetInteractableComponents_Implementation()
PURE_VIRTUAL(AInteractable::GetInteractableComponents_Implementation, return {};);
void Activate(EActivatorType type);
virtual void Activate_Implementation(EActivatorType type) {}
void _Deactivate(EActivatorType type);
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void Deactivate(EActivatorType type);
virtual void Deactivate_Implementation(EActivatorType type) {}
protected:
virtual void BeginPlay() override;
UPROPERTY(BlueprintReadWrite, meta = (Bitmask, BitmaskEnum = "EActivatorType"))
uint8 activated = 0;
UPROPERTY(EditDefaultsOnly)
TArray<TSubclassOf<class UInteractableModificator>> modificatorsClasses;
private:
//UPROPERTY(EditDefaultsOnly)
//TSoftObjectPtr<UMaterialInstance> material;
TArray<class UInteractableModificator*> _modificators;
};

View File

@ -1,20 +0,0 @@
// Oleg Petruny proprietary.
#include "InteractableCaller.h"
UInteractableCaller::UInteractableCaller(const FObjectInitializer& ObjectInitializer)
: UActorComponent(ObjectInitializer)
{
if(HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject))
{
return;
}
RegisterComponent();
}
void UInteractableCaller::Init()
{
//GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, GetOwner()->GetName());
}

View File

@ -1,19 +0,0 @@
// Oleg Petruny proprietary.
#pragma once
#include "Components/ActorComponent.h"
#include "CoreMinimal.h"
#include "InteractableCaller.generated.h"
UCLASS(Abstract, Blueprintable, BlueprintType)
class UInteractableCaller : public UActorComponent
{
GENERATED_BODY()
public:
UInteractableCaller(const FObjectInitializer& ObjectInitializer);
void Init();
};

View File

@ -1,5 +0,0 @@
// Oleg Petruny proprietary.
#include "InteractableComponent.h"

View File

@ -1,29 +0,0 @@
// Oleg Petruny proprietary.
#pragma once
#include "CoreMinimal.h"
#include "InputMappingContext.h"
#include "UObject/Interface.h"
#include "InteractableActivator.h"
#include "InteractableComponent.generated.h"
UCLASS(Abstract, Blueprintable, BlueprintType)
class UInteractableComponent : public UActorComponent
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
const FString GetName();
virtual const FString GetName_Implementation()
PURE_VIRTUAL(UInteractableComponent::GetInteractionName_Implementation, return "NONE";);
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
const TArray<TSubclassOf<UInteractableActivator>> GetActivators();
virtual const TArray<TSubclassOf<UInteractableActivator>> GetActivators_Implementation()
PURE_VIRTUAL(UInteractableComponent::GetActivatorsZ_Implementation,
TArray<TSubclassOf<UInteractableActivator>> _activators{}; return _activators;);
};

View File

@ -0,0 +1,16 @@
// Oleg Petruny proprietary.
#include "InteractableModificator.h"
#include "InputMappingContext.h"
const UInputMappingContext* UInteractableModificator::GetMappingContext() const
{
return inputMapping.LoadSynchronous();
}
EActivatorType UInteractableModificator::GetActivatorTypes() const
{
return static_cast<EActivatorType>(activatorTypes);
}

View File

@ -0,0 +1,27 @@
// Oleg Petruny proprietary.
#pragma once
#include "Components/ActorComponent.h"
#include "CoreMinimal.h"
#include "InteractableModificator.generated.h"
enum class EActivatorType : uint8;
UCLASS(Abstract, Blueprintable, BlueprintType)
class UInteractableModificator : public UActorComponent
{
GENERATED_BODY()
public:
const class UInputMappingContext* GetMappingContext() const;
EActivatorType GetActivatorTypes() const;
protected:
UPROPERTY(EditDefaultsOnly)
TSoftObjectPtr<class UInputMappingContext> inputMapping;
UPROPERTY(EditAnywhere, meta = (Bitmask, BitmaskEnum = "EActivatorType"))
uint8 activatorTypes = 0;
};

View File

@ -0,0 +1,5 @@
// Oleg Petruny proprietary.
#include "InteractableUsableModificator.h"

View File

@ -0,0 +1,18 @@
// Oleg Petruny proprietary.
#pragma once
#include "InteractableModificator.h"
#include "InteractableUsableModificator.generated.h"
UCLASS(Blueprintable, BlueprintType)
class UInteractableUsableModificator : public UInteractableModificator
{
GENERATED_BODY()
public:
protected:
};

View File

@ -1,21 +0,0 @@
// Oleg Petruny proprietary.
#include "SawInteractable.h"
#include "InCameraInteractableActivator.h"
#include "InteractableCaller.h"
const FString USawInteractable::GetName_Implementation()
{
static auto _name = TEXT("Saw");
return _name;
}
const TArray<TSubclassOf<UInteractableActivator>> USawInteractable::GetActivators_Implementation()
{
static TArray<TSubclassOf<UInteractableActivator>> _array = {
{UInCameraInteractableActivator::StaticClass()}
};
return _array;
}

View File

@ -1,23 +0,0 @@
// Oleg Petruny proprietary.
#pragma once
#include "CoreMinimal.h"
#include "InteractableComponent.h"
#include "SawInteractable.generated.h"
UCLASS(Blueprintable, BlueprintType)
class USawInteractable : public UInteractableComponent
{
GENERATED_BODY()
public:
const FString GetName();
virtual const FString GetName_Implementation() override;
const TArray<TSubclassOf<UInteractableActivator>> GetActivators();
virtual const TArray<TSubclassOf<UInteractableActivator>> GetActivators_Implementation() override;
};

View File

@ -1,20 +0,0 @@
// Oleg Petruny proprietary.
#include "UsableInteractable.h"
#include "RaycastInteractableActivator.h"
const FString UUsableInteractable::GetName_Implementation()
{
static auto _name = TEXT("Use");
return _name;
}
const TArray<TSubclassOf<UInteractableActivator>> UUsableInteractable::GetActivators_Implementation()
{
static TArray<TSubclassOf<UInteractableActivator>> _array = {
{URaycastInteractableActivator::StaticClass()}
};
return _array;
}

View File

@ -1,23 +0,0 @@
// Oleg Petruny proprietary.
#pragma once
#include "CoreMinimal.h"
#include "InteractableComponent.h"
#include "UsableInteractable.generated.h"
UCLASS(Blueprintable, BlueprintType)
class UUsableInteractable : public UInteractableComponent
{
GENERATED_BODY()
public:
const FString GetName();
virtual const FString GetName_Implementation() override;
const TArray<TSubclassOf<UInteractableActivator>> GetActivators();
virtual const TArray<TSubclassOf<UInteractableActivator>> GetActivators_Implementation() override;
};

View File

@ -9,8 +9,9 @@
#include "UObject/ScriptInterface.h"
#include "CustomGameInstanceBase.h"
#include "Interactable/InteractableComponent.h"
#include "WidgetsManager.h"
#include "Widgets/WidgetsManager.h"
UWidgetsManager* AMainGameModeBase::_widgetsManager = nullptr;
void AMainGameModeBase::StartPlay()
{
@ -37,6 +38,11 @@ bool AMainGameModeBase::SetPause(APlayerController* PC, FCanUnpause CanUnpauseDe
return AGameModeBase::SetPause(PC, CanUnpauseDelegate);
}
UWidgetsManager* AMainGameModeBase::GetWidgetManager()
{
return _widgetsManager;
}
void AMainGameModeBase::SwitchCameraMode()
{
static TWeakObjectPtr<APawn> _playerPawn = nullptr;

View File

@ -18,10 +18,12 @@ public:
void SwitchCameraMode();
static class UWidgetsManager* GetWidgetManager();
protected:
UPROPERTY(EditDefaultsOnly)
TSubclassOf<class UWidgetsManager> widgetManagerClass;
private:
class UWidgetsManager* _widgetsManager;
static class UWidgetsManager* _widgetsManager;
};

View File

@ -11,11 +11,7 @@
#include "Kismet/KismetMathLibrary.h"
#include "CustomGameInstanceBase.h"
#include "Interactable/Interactable.h"
#include "Interactable/InteractableActivator.h"
#include "Interactable/InteractableCaller.h"
#include "Interactable/InteractableComponent.h"
#include "Interactable/UsableInteractable.h"
#include "Interactable/Activators/InteractableActivator.h"
#include "CustomGameUserSettings.h"
#include "MainGameModeBase.h"
@ -73,7 +69,7 @@ void APlayerBase::BeginPlay()
}
}
LoadInteractable();
LoadInteractablesActivators();
}
void APlayerBase::SwitchToCameraPawn()
@ -136,33 +132,46 @@ void APlayerBase::UpdatePitch(float min, float max)
}
}
void APlayerBase::LoadInteractable()
void APlayerBase::LoadInteractablesActivators()
{
auto GI = Cast<UCustomGameInstanceBase>(GetWorld()->GetGameInstance());
if(!GI)
if(auto GI = Cast<UCustomGameInstanceBase>(GetWorld()->GetGameInstance()))
{
return;
}
TSet<UClass*> instancedActivators;
for(auto& act : GI->interactionsActivators)
{
if(instancedActivators.Contains(act))
continue;
instancedActivators.Add(act);
TSet<TSubclassOf<UInteractableActivator>> activators;
for(auto& interaction : GI->interactionsActivators)
{
auto actArray = interaction->GetDefaultObject<UInteractableComponent>()->GetActivators_Implementation();
for(auto& act : actArray)
{
if(!activators.Contains(act))
{
activators.Add(act);
auto component = NewObject<UInteractableActivator>(this, act);
component->interactableActivatedDelegate.BindUObject(this, &APlayerBase::InteractableActivated);
component->interactableDeactivatedDelegate.BindUObject(this, &APlayerBase::InteractableDeactivated);
component->SetupAttachment(camera);
component->RegisterComponent();
}
}
}
}
void APlayerBase::InteractableActivated(AInteractable* interactable)
void APlayerBase::InteractableActivated(AInteractable* interactable, EActivatorType type)
{
GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Cyan, TEXT("Player activate: ") + interactable->GetName());
if(interactionLocked)
return;
interactable->Activate(type);
#ifdef INTERACTABLE_DEBUG
GEngine->AddOnScreenDebugMessage(30 + (int)type, 5.0f, FColor::Cyan, TEXT("Player activate: ") + interactable->GetName()
+ TEXT(" by: ") + StaticEnum<EActivatorType>()->GetNameByValue(static_cast<int64>(type)).ToString());
#endif // INTERACTABLE_DEBUG
}
void APlayerBase::InteractableDeactivated(AInteractable* interactable, EActivatorType type)
{
if(interactionLocked)
return;
interactable->Deactivate(type);
#ifdef INTERACTABLE_DEBUG
GEngine->AddOnScreenDebugMessage(30 + (int)type, 5.0f, FColor::Magenta, TEXT("Player deactivate: ") + interactable->GetName()
+ TEXT(" by: ") + StaticEnum<EActivatorType>()->GetNameByValue(static_cast<int64>(type)).ToString());
#endif // INTERACTABLE_DEBUG
}

View File

@ -5,6 +5,8 @@
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Interactable/Interactable.h"
#include "PlayerBase.generated.h"
UCLASS()
@ -49,6 +51,8 @@ protected:
bool jumpLocked = false;
UPROPERTY(EditAnywhere)
bool runLocked = false;
UPROPERTY(EditAnywhere)
bool interactionLocked = false;
APlayerCameraManager* cameraManager;
class UCameraComponent* camera;
@ -60,6 +64,7 @@ protected:
float maxPitch = 65;
private:
void LoadInteractable();
void InteractableActivated(class AInteractable* interactable);
void LoadInteractablesActivators();
void InteractableActivated(AInteractable* interactable, EActivatorType type);
void InteractableDeactivated(AInteractable* interactable, EActivatorType type);
};

View File

@ -0,0 +1,5 @@
// Oleg Petruny proprietary.
#include "InteractableHintWidget.h"

View File

@ -0,0 +1,23 @@
// Oleg Petruny proprietary.
#pragma once
#include "Blueprint/UserWidget.h"
#include "CoreMinimal.h"
#include "InteractableHintWidget.generated.h"
UCLASS(Blueprintable)
class UInteractableHintWidget : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void Show();
virtual void Show_Implementation() {}
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void Proceed();
virtual void Proceed_Implementation() {}
};

View File

@ -0,0 +1,4 @@
// Oleg Petruny proprietary.
#include "InteractableHintWidgetManager.h"

View File

@ -0,0 +1,35 @@
// Oleg Petruny proprietary.
#pragma once
#include "Blueprint/UserWidget.h"
#include "CoreMinimal.h"
#include "InteractableHintWidgetManager.generated.h"
enum class EActivatorType : uint8;
UCLASS(Blueprintable)
class UInteractableHintWidgetManager : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void Append(const class UInteractableModificator* modificator);
virtual void Append_Implementation(const class UInteractableModificator* modificator) {}
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void Remove(EActivatorType type);
virtual void Remove_Implementation(EActivatorType type) {}
protected:
UPROPERTY(EditDefaultsOnly)
TSubclassOf<class UInteractableHintWidget> interactableHintPressWidgetClass;
class UInteractableHintWidget* interactableHintPressWidget;
UPROPERTY(EditDefaultsOnly)
TSubclassOf<class UInteractableHintWidget> interactableHintHoldWidgetClass;
class UInteractableHintWidget* interactableHintHoldWidget;
};

View File

@ -5,12 +5,14 @@
#include "Blueprint/UserWidget.h"
#include "Engine/World.h"
#include "InputMappingContext.h"
#include "Kismet/GameplayStatics.h"
#include "UObject/ScriptInterface.h"
#include "CustomGameInstanceBase.h"
#include "Interactable/Interactable.h"
#include "Interactable/InteractableComponent.h"
#include "Interactable/Modificators/InteractableModificator.h"
#include "InteractableHintWidgetManager.h"
void UWidgetsManager::Init()
{
@ -33,6 +35,8 @@ void UWidgetsManager::Init()
}
}
}
interactableHintWidgetManager = NewObject<UInteractableHintWidgetManager>(this, interactableHintWidgetManagerClass);
}
void UWidgetsManager::HideOverlayWidgets()
@ -78,8 +82,11 @@ void UWidgetsManager::UpdateOverlayWidgetsOwner()
}
}
void UWidgetsManager::ShowInteractionHints(AInteractable* interactable)
void UWidgetsManager::ShowInteractionHints(const UInteractableModificator* modificator)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, TEXT("Interaction Hint"));
//interactable->GetInterfa
interactableHintWidgetManager->Append(modificator);
}
void UWidgetsManager::HideInteractionHints(const EActivatorType type)
{
interactableHintWidgetManager->Remove(type);
}

View File

@ -1,5 +1,3 @@
#pragma once
// Oleg Petruny proprietary.
#pragma once
@ -9,6 +7,8 @@
#include "WidgetsManager.generated.h"
enum class EActivatorType : uint8;
UCLASS(Blueprintable)
class UWidgetsManager : public UObject
{
@ -21,7 +21,8 @@ public:
void ShowOverlayWidgets();
void UpdateOverlayWidgetsOwner();
void ShowInteractionHints(class AInteractable* interactable);
void ShowInteractionHints(const class UInteractableModificator* modificator);
void HideInteractionHints(const EActivatorType type);
protected:
UPROPERTY(EditDefaultsOnly)
@ -31,4 +32,8 @@ protected:
UPROPERTY(EditDefaultsOnly)
TArray<TSubclassOf<class UUserWidget>> overlayWidgets; // hidden in pause
TArray<TWeakObjectPtr<class UUserWidget>> overlayWidgetsInstances;
UPROPERTY(EditDefaultsOnly)
TSubclassOf<class UInteractableHintWidgetManager> interactableHintWidgetManagerClass;
class UInteractableHintWidgetManager* interactableHintWidgetManager;
};

View File

@ -16,8 +16,8 @@ public:
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER_SRV(Buffer<unsigned int>, Input)
SHADER_PARAMETER_UAV(RWBuffer<unsigned int>, Output)
SHADER_PARAMETER_SRV(Buffer<uint>, Input)
SHADER_PARAMETER_UAV(RWBuffer<uint>, Output)
END_SHADER_PARAMETER_STRUCT()