Interactables

This commit is contained in:
Oleg Petruny 2024-12-10 22:34:23 +01:00
parent 33cbfe1a18
commit 0226afe5ae
20 changed files with 90 additions and 57 deletions

View File

@ -9,7 +9,7 @@
/**
* Activates interactable only once if is in a camera view
*/
UCLASS(Blueprintable, BlueprintType, meta = (BlueprintSpawnableComponent, ShortTooltip = "Activates interactable only once if is in a camera view"), MinimalAPI)
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableActivator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Activates interactable only once if is in a camera view"), MinimalAPI)
class UInCameraInteractableActivator : public UInteractableActivator
{
GENERATED_BODY()
@ -38,7 +38,7 @@ protected:
* @param interactable .. interactable activated
*/
UFUNCTION(BlueprintImplementableEvent)
virtual void OnNewSeenInteractable(class AInteractable* interactable);
void OnNewSeenInteractable(class AInteractable* interactable);
private:
UPROPERTY()

View File

@ -1,6 +1,5 @@
// Oleg Petruny proprietary.
#include "InteractableActivator.h"
#include "Engine/CollisionProfile.h"

View File

@ -11,7 +11,10 @@
DECLARE_DELEGATE_TwoParams(FInteractableActivated, AInteractable*, EActivatorType);
DECLARE_DELEGATE_TwoParams(FInteractableDeactivated, AInteractable*, EActivatorType);
UCLASS(Abstract, Blueprintable, BlueprintType)
/**
* Activates interactable based on type
*/
UCLASS(Abstract, Blueprintable, BlueprintType, ClassGroup = InteractableActivator, meta = (ShortTooltip = "Activates interactable based on type"), MinimalAPI)
class UInteractableActivator : public USceneComponent
{
GENERATED_BODY()
@ -20,14 +23,16 @@ public:
UInteractableActivator(const FObjectInitializer& ObjectInitializer);
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
/** Resets activator state forcing to rescan */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
LOST_EDGE_API void Rescan();
virtual void Rescan_Implementation() {}
virtual void Rescan_Implementation() PURE_VIRTUAL(UInteractableActivator::Scan_Implementation, );
FInteractableActivated interactableActivatedDelegate;
FInteractableActivated interactableDeactivatedDelegate;
protected:
/** Activator scan function in game thread tick */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
LOST_EDGE_API void Scan();
virtual void Scan_Implementation() PURE_VIRTUAL(UInteractableActivator::Scan_Implementation, );

View File

@ -9,7 +9,9 @@
DECLARE_DELEGATE_OneParam(FInteractableInScreen, class AInteractable*);
/**
* Notifies only once about interactable is in a camera view
*/
UCLASS(BlueprintType, hidecategories = (Collision, Object, Physics, SceneComponent), ClassGroup = Rendering, editinlinenew, meta = (BlueprintSpawnableComponent, ShortTooltip = "Notifies only once about interactable is in a camera view"), MinimalAPI)
class UInteractableScreenCapturer : public USceneCaptureComponent2D
{

View File

@ -9,7 +9,7 @@
/**
* Activates interactable with a single raycast from a camera center
*/
UCLASS(Blueprintable, BlueprintType, meta = (BlueprintSpawnableComponent, ShortTooltip = "Activates interactable with a single raycast from a camera center"), MinimalAPI)
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableActivator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Activates interactable with a single raycast from a camera center"), MinimalAPI)
class URaycastInteractableActivator : public UInteractableActivator
{
GENERATED_BODY()

View File

@ -1,6 +1,5 @@
// Oleg Petruny proprietary.
#include "Interactable.h"
#include "Kismet/GameplayStatics.h"
@ -86,13 +85,13 @@ void AInteractable::EndPlay(const EEndPlayReason::Type EndPlayReason)
if(activated)
{
activationLockers.Empty();
_Deactivate(static_cast<EActivatorType>(activated));
Deactivate(static_cast<EActivatorType>(activated));
}
Super::EndPlay(EndPlayReason);
}
void AInteractable::_Activate(EActivatorType type)
void AInteractable::Activate(EActivatorType type)
{
#ifdef INTERACTABLE_DEBUG
GEngine->AddOnScreenDebugMessage(30 + (int)type, 5.0f, FColor::Cyan, TEXT("Player activate: ") + this->GetName()
@ -127,7 +126,7 @@ void AInteractable::_Activate(EActivatorType type)
Activate(type);
}
void AInteractable::_Deactivate(EActivatorType type)
void AInteractable::Deactivate(EActivatorType type)
{
#ifdef INTERACTABLE_DEBUG
GEngine->AddOnScreenDebugMessage(30 + (int)type, 5.0f, FColor::Magenta, TEXT("Player deactivate: ") + this->GetName()

View File

@ -2,15 +2,18 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Interactable.generated.h"
/** Turns on debug of interactable objects */
//#define INTERACTABLE_DEBUG
/** Turns on debug of interactable activator components */
//#define INTERACTABLE_ACTIVATOR_DEBUG
/** Turns on debug of interactable modificator components */
//#define INTERACTABLE_MODIFICATOR_DEBUG
/** Defines activation types */
UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true"))
enum class EActivatorType : uint8
{
@ -27,38 +30,52 @@ enum class EActivatorType : uint8
};
ENUM_CLASS_FLAGS(EActivatorType);
/**
* Object capable of reacting to activators and execute modificators.
* Sets all needed settings as collision layers on begin play.
*/
UCLASS(Blueprintable, BlueprintType, MinimalAPI)
class AInteractable : public AActor
{
GENERATED_BODY()
public:
/** Returns flags mask of activated types */
int32 GetActivatedFlags();
void _Activate(EActivatorType type);
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
/** Receives activate signal from activator of specific type and activates all modificators of that type */
UFUNCTION(BlueprintCallable)
void Activate(EActivatorType type);
virtual void Activate_Implementation(EActivatorType type) {}
void _Deactivate(EActivatorType type);
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
/** Receives deactivate signal from activator of specific type and deactivates all modificators of that type */
UFUNCTION(BlueprintCallable)
void Deactivate(EActivatorType type);
virtual void Deactivate_Implementation(EActivatorType type) {}
/**
* All modificators that requires (de)activation lock for current interactable.
* Used manually by modificators to handle operations which can be continued after physical deactivation.
* Eg. MoveModificator movement while mouse buttons are down even if player don't activating interactable anymore.
*/
TSet<class UInteractableModificator*> activationLockers;
protected:
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
UFUNCTION(BlueprintImplementableEvent)
void OnActivate(EActivatorType type);
UFUNCTION(BlueprintImplementableEvent)
void OnDeactivate(EActivatorType type);
/** Mask of active activator types */
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (Bitmask, BitmaskEnum = "EActivatorType"))
int32 activated = 0;
/** Map of modificators to activator types initialized on BeginPlay */
UPROPERTY()
TMap<EActivatorType, class UInteractableModificator*> modificators;
class APlayerBase* player = nullptr;
TArray<UPrimitiveComponent*> collisions;
class APlayerBase* player = nullptr;
};

View File

@ -1,6 +1,5 @@
// Oleg Petruny proprietary.
#include "ActivateInteractableModificator.h"
#include "EnhancedInputComponent.h"

View File

@ -2,14 +2,16 @@
#pragma once
#include "CoreMinimal.h"
#include "InteractableModificator.h"
#include "ActivateInteractableModificator.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FActivateInteractableModificatorActivatedDelegate);
UCLASS(ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent), Blueprintable, BlueprintType)
/**
* Basic modificator for type Use
*/
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Basic modificator for type Use"), MinimalAPI)
class UActivateInteractableModificator : public UInteractableModificator
{
GENERATED_BODY()

View File

@ -1,14 +1,11 @@
// Oleg Petruny proprietary.
#include "EditInteractableModificator.h"
#include "Interactable/Interactable.h"
UEditInteractableModificator::UEditInteractableModificator(const FObjectInitializer& ObjectInitializer)
: UInteractableModificator(ObjectInitializer)
{
activatorTypes |= static_cast<uint8>(EActivatorType::Collide);
}
//UEditInteractableModificator::UEditInteractableModificator(const FObjectInitializer& ObjectInitializer)
// : UInteractableModificator(ObjectInitializer)
//{
// activatorTypes |= static_cast<uint8>(EActivatorType::Collide);
//}

View File

@ -2,17 +2,20 @@
#pragma once
#include "CoreMinimal.h"
#include "InteractableModificator.h"
#include "EditInteractableModificator.generated.h"
//#include "EditInteractableModificator.generated.h"
UCLASS(ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent), Blueprintable, BlueprintType)
class UEditInteractableModificator : public UInteractableModificator
{
GENERATED_BODY()
public:
UEditInteractableModificator(const FObjectInitializer& ObjectInitializer);
};
/**
* <WIP>
* Edits object topology on collision
*/
//UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Edits object topology on collision"), MinimalAPI)
//class UEditInteractableModificator : public UInteractableModificator
//{
// GENERATED_BODY()
//
//public:
// UEditInteractableModificator(const FObjectInitializer& ObjectInitializer);
//
//};

View File

@ -1,6 +1,5 @@
// Oleg Petruny proprietary.
#include "InteractableModificator.h"
#include "InputMappingContext.h"

View File

@ -3,29 +3,37 @@
#pragma once
#include "Components/ActorComponent.h"
#include "CoreMinimal.h"
#include "InteractableModificator.generated.h"
enum class EActivatorType : uint8;
UCLASS(Abstract, Blueprintable, BlueprintType)
/**
* Do something on activation by specified activator types
*/
UCLASS(Abstract, Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Do something on activation by specified activator types"), MinimalAPI)
class UInteractableModificator : public UActorComponent
{
GENERATED_BODY()
public:
/** Append itself to CustomGameInstance modificators registry */
void OnRegister() override;
/** Returns input mappings assigned in constructor */
UFUNCTION(BlueprintCallable)
const class UInputMappingContext* GetMappingContext() const;
/** Filters activation type in interractable */
UFUNCTION(BlueprintCallable)
EActivatorType GetActivatorTypes() const;
/** Called from interactable on activation (mostly used to bind input context to internal modificator functions) */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void Bind(class UEnhancedInputComponent* input);
virtual void Bind_Implementation(class UEnhancedInputComponent* input) {}
/** Called from interactable on deactivation (mostly used to unbind input context from internal functions) */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void Unbind();
virtual void Unbind_Implementation() {}

View File

@ -1,6 +1,5 @@
// Oleg Petruny proprietary.
#include "InventoryInteractableModificator.h"
#include "EnhancedInputComponent.h"

View File

@ -2,12 +2,14 @@
#pragma once
#include "CoreMinimal.h"
#include "InteractableModificator.h"
#include "InventoryInteractableModificator.generated.h"
UCLASS(ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent), Blueprintable, BlueprintType)
/**
* Modificator of type Use for storing items in a APlayerBase
*/
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Modificator of type Use for storing items in a APlayerBase"), MinimalAPI)
class UInventoryInteractableModificator : public UInteractableModificator
{
GENERATED_BODY()

View File

@ -1,6 +1,5 @@
// Oleg Petruny proprietary.
#include "MoveInteractableModificator.h"
#include "EnhancedInputComponent.h"
@ -90,7 +89,7 @@ void UMoveInteractableModificator::Unbind_Implementation()
bindindingHandlers.Empty();
SetComponentTickEnabled(false);
actor->_Deactivate(GetActivatorTypes());
actor->Deactivate(GetActivatorTypes());
OnMoveDeactivated.Broadcast();
}

View File

@ -2,7 +2,6 @@
#pragma once
#include "CoreMinimal.h"
#include "InputActionValue.h"
#include "InteractableModificator.h"
@ -13,7 +12,10 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDeactivateMoveInteractableModificatorActivat
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FHoldingMoveInteractableModificatorActivatedDelegate);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FRotatingMoveInteractableModificatorActivatedDelegate);
UCLASS(ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent), Blueprintable, BlueprintType)
/**
* Basic modificator for Move type activator
*/
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Basic modificator for Move type activator"), MinimalAPI)
class UMoveInteractableModificator : public UInteractableModificator
{
GENERATED_BODY()

View File

@ -1,6 +1,5 @@
// Oleg Petruny proprietary.
#include "SawInteractableModificator.h"
#include "Interactable/Interactable.h"

View File

@ -2,14 +2,16 @@
#pragma once
#include "CoreMinimal.h"
#include "InteractableModificator.h"
#include "SawInteractableModificator.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FSawInteractableModificatorActivatedDelegate);
UCLASS(ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent), Blueprintable, BlueprintType)
/**
* Basic modificator for Saw type activator
*/
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Basic modificator for Saw type activator"), MinimalAPI)
class USawInteractableModificator : public UInteractableModificator
{
GENERATED_BODY()

View File

@ -284,7 +284,7 @@ void APlayerBase::InteractableActivated(AInteractable* interactable, EActivatorT
if(interactionLocked || interactable->IsHidden())
return;
interactable->_Activate(type);
interactable->Activate(type);
if(interactable != lastInteractable)
lastInteractable = interactable;
@ -295,7 +295,7 @@ void APlayerBase::InteractableDeactivated(AInteractable* interactable, EActivato
if(!interactable)
return;
interactable->_Deactivate(type);
interactable->Deactivate(type);
if(interactable->GetActivatedFlags() == 0)
lastInteractable = nullptr;