Rework interaction system

This commit is contained in:
2026-05-28 21:53:34 +03:00
parent 891a0744a0
commit 6f0aa5274c
26 changed files with 496 additions and 216 deletions
@@ -1,55 +0,0 @@
// © 2025 Naked People Team. All Rights Reserved.
#include "InteractableBase.h"
#include "Components/WidgetComponent.h"
#include "Kismet/GameplayStatics.h"
#include "NakedDesire/InteractionSystem/InteractionManager.h"
#include "NakedDesire/Player/NakedDesireCharacter.h"
AInteractableBase::AInteractableBase()
{
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.TickInterval = 0.25f;
RootSceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
RootComponent = RootSceneComponent;
WidgetAnchor = CreateDefaultSubobject<USceneComponent>(TEXT("Widget Anchor"));
WidgetAnchor->SetupAttachment(RootComponent);
InteractionTrigger = CreateDefaultSubobject<UWidgetComponent>(TEXT("Interaction Trigger"));
InteractionTrigger->SetupAttachment(WidgetAnchor);
InteractionTrigger->SetDrawSize(FVector2D(35, 35));
InteractionTrigger->SetWidgetSpace(EWidgetSpace::Screen);
InteractionTrigger->SetWindowFocusable(false);
}
void AInteractableBase::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
if (!Player)
{
if (ACharacter* PlayerCharacter = UGameplayStatics::GetPlayerCharacter(GetWorld(), 0))
{
Player = Cast<ANakedDesireCharacter>(PlayerCharacter);
}
}
if (Player)
{
const TScriptInterface<IInteractionTarget> NearestInteractionTarget = Player->InteractionManager->GetNearestInteractionTarget();
if (NearestInteractionTarget.GetObject() == this)
{
InteractionTrigger->SetVisibility(true);
}
else
{
InteractionTrigger->SetVisibility(false);
}
}
}
@@ -1,34 +0,0 @@
// © 2025 Naked People Team. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "NakedDesire/InteractionSystem/InteractionTarget.h"
#include "InteractableBase.generated.h"
class ANakedDesireCharacter;
class UWidgetComponent;
UCLASS()
class NAKEDDESIRE_API AInteractableBase : public AActor, public IInteractionTarget
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly)
USceneComponent* RootSceneComponent = nullptr;
UPROPERTY(EditDefaultsOnly)
USceneComponent* WidgetAnchor = nullptr;
UPROPERTY(EditDefaultsOnly)
UWidgetComponent* InteractionTrigger = nullptr;
UPROPERTY()
ANakedDesireCharacter* Player = nullptr;
public:
AInteractableBase();
virtual void Tick(float DeltaSeconds) override;
};
@@ -0,0 +1,76 @@
// © 2025 Naked People Team. All Rights Reserved.
#include "ItemPickup.h"
#include "Components/BoxComponent.h"
#include "Components/WidgetComponent.h"
#include "NakedDesire/Clothing/ClothingItem.h"
#include "NakedDesire/Clothing/ClothingItemInstance.h"
#include "NakedDesire/Clothing/ClothingManager.h"
#include "NakedDesire/Player/NakedDesireCharacter.h"
AItemPickup::AItemPickup()
{
Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
SetRootComponent(Mesh);
Mesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Collider = CreateDefaultSubobject<UBoxComponent>(TEXT("Collider"));
Collider->SetupAttachment(RootComponent);
Collider->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
InteractionHint = CreateDefaultSubobject<UWidgetComponent>(TEXT("Interaction Hint"));
InteractionHint->SetupAttachment(RootComponent);
}
void AItemPickup::Interact_Implementation(ANakedDesireCharacter* Player)
{
if (ClothingItemInstance)
{
Player->ClothingManager->TakeClothing(ClothingItemInstance);
Destroy();
}
}
bool AItemPickup::CanInteract_Implementation(ANakedDesireCharacter* Player) const
{
return ClothingItemInstance != nullptr;
}
void AItemPickup::HideInteractionHint_Implementation()
{
ApplyOutline(Mesh, false, 0);
InteractionHint->SetVisibility(false);
}
void AItemPickup::ShowInteractionFocusHint_Implementation()
{
ApplyOutline(Mesh, true, 2);
InteractionHint->SetVisibility(true);
}
void AItemPickup::ShowInteractionProximityHint_Implementation()
{
ApplyOutline(Mesh, true, 1);
InteractionHint->SetVisibility(false);
}
void AItemPickup::BeginPlay()
{
Super::BeginPlay();
InteractionHint->SetVisibility(false);
}
void AItemPickup::SetItem(UClothingItemInstance* InItem)
{
ClothingItemInstance = InItem;
Mesh->SetStaticMesh(InItem->GetClothingItem()->StaticMesh);
}
void AItemPickup::ApplyOutline(UStaticMeshComponent* InMesh, bool bEnabled, int32 StencilValue)
{
InMesh->SetRenderCustomDepth(bEnabled);
InMesh->SetCustomDepthStencilValue(StencilValue);
}
@@ -0,0 +1,49 @@
// © 2025 Naked People Team. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "NakedDesire/Interaction/Interactable.h"
#include "ItemPickup.generated.h"
class UWidgetComponent;
class UBoxComponent;
class UClothingItemInstance;
UCLASS(Abstract)
class NAKEDDESIRE_API AItemPickup : public AActor, public IInteractable
{
GENERATED_BODY()
AItemPickup();
public:
virtual void Interact_Implementation(ANakedDesireCharacter* Player) override;
virtual bool CanInteract_Implementation(ANakedDesireCharacter* Player) const override;
virtual void HideInteractionHint_Implementation() override;
virtual void ShowInteractionFocusHint_Implementation() override;
virtual void ShowInteractionProximityHint_Implementation() override;
void SetItem(UClothingItemInstance* InItem);
UClothingItemInstance* GetItem() const { return ClothingItemInstance; }
protected:
virtual void BeginPlay() override;
private:
UPROPERTY()
TObjectPtr<UClothingItemInstance> ClothingItemInstance;
UPROPERTY(EditDefaultsOnly)
TObjectPtr<UStaticMeshComponent> Mesh;
UPROPERTY(EditDefaultsOnly)
TObjectPtr<UBoxComponent> Collider;
UPROPERTY(EditDefaultsOnly)
TObjectPtr<UWidgetComponent> InteractionHint;
void ApplyOutline(UStaticMeshComponent* InMesh, bool bEnabled, int32 StencilValue);
};
@@ -2,7 +2,6 @@
#include "Wardrobe.h"
#include "Kismet/GameplayStatics.h"
#include "NakedDesire/SaveGame/GlobalSaveGameData.h"
#include "NakedDesire/SaveGame/ItemSaveRecord.h"
+2 -2
View File
@@ -3,14 +3,13 @@
#pragma once
#include "CoreMinimal.h"
#include "InteractableBase.h"
#include "GameFramework/Actor.h"
#include "Wardrobe.generated.h"
class UClothingItemInstance;
UCLASS(Blueprintable)
class NAKEDDESIRE_API AWardrobe : public AInteractableBase
class NAKEDDESIRE_API AWardrobe : public AActor
{
GENERATED_BODY()
@@ -21,5 +20,6 @@ public:
void AddItem(UClothingItemInstance* ClothingItemInstance);
void RemoveItem(UClothingItemInstance* ClothingItemInstance) const;
protected:
virtual void BeginPlay() override;
};