Setup player preview for equipment panel

This commit is contained in:
2026-05-31 15:33:43 +03:00
parent 2969800966
commit aefabc8ed7
42 changed files with 823 additions and 318 deletions
-7
View File
@@ -15,10 +15,3 @@ ANPC::ANPC()
AutoPossessAI = EAutoPossessAI::PlacedInWorldOrSpawned;
}
void ANPC::Destroyed()
{
Super::Destroyed();
OnDestroyed.Broadcast(this);
}
-7
View File
@@ -8,8 +8,6 @@
class ANPC;
DECLARE_MULTICAST_DELEGATE_OneParam(FOnNPCDestroyed, ANPC* NPC);
UCLASS()
class NAKEDDESIRE_API ANPC : public ACharacter
{
@@ -17,9 +15,4 @@ class NAKEDDESIRE_API ANPC : public ACharacter
public:
ANPC();
FOnNPCDestroyed OnDestroyed;
protected:
virtual void Destroyed() override;
};
+17 -28
View File
@@ -2,44 +2,29 @@
#include "NPCAIController.h"
#include "NavigationSystem.h"
#include "NPCTargetLocation.h"
#include "AI/NavigationSystemBase.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Perception/AISense_Sight.h"
#include "NakedDesire/Global/NakedDesireGameMode.h"
#include "Perception/AISenseConfig_Sight.h"
#include "NakedDesire/Player/NakedDesireCharacter.h"
#include "NakedDesire/Stats/StatsManager.h"
#include "Perception/AIPerceptionComponent.h"
void ANPCAIController::SetShouldReactToPlayer(const bool Value)
ANPCAIController::ANPCAIController()
{
Blackboard->SetValueAsBool(FName(TEXT("ShouldReactToPlayer")), Value);
UAIPerceptionComponent* Perception = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("PerceptionComponent"));
SetPerceptionComponent(*Perception);
UAISenseConfig_Sight* SightConfig = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("SightConfig"));
SightConfig->DetectionByAffiliation.bDetectEnemies = true;
SightConfig->DetectionByAffiliation.bDetectNeutrals = true;
SightConfig->DetectionByAffiliation.bDetectFriendlies = true;
Perception->ConfigureSense(*SightConfig);
Perception->SetDominantSense(SightConfig->GetSenseImplementation());
}
void ANPCAIController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
NavigationSystem = FNavigationSystem::GetCurrent<UNavigationSystemV1>(GetWorld());
GameMode = Cast<ANakedDesireGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
RunBehaviorTree(BehaviorTreeAsset);
const FVector SpawnLocation = InPawn->GetActorLocation();
TArray<AActor*> TargetActors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), ANPCTargetLocation::StaticClass(), TargetActors);
const int RandomIndex = FMath::RandRange(0, TargetActors.Num() - 1);
Blackboard->SetValueAsVector("TargetLocation", TargetActors[RandomIndex]->GetActorLocation());
Blackboard->SetValueAsVector("SpawnLocation", SpawnLocation);
PlayerCharacter = Cast<ANakedDesireCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
Blackboard->SetValueAsObject("Player", PlayerCharacter);
PerceptionComponent->OnTargetPerceptionUpdated.AddUniqueDynamic(this, &ANPCAIController::OnTargetPerceptionUpdate);
}
@@ -55,11 +40,15 @@ void ANPCAIController::OnUnPossess()
void ANPCAIController::OnTargetPerceptionUpdate(AActor* Actor, FAIStimulus Stimulus)
{
if (Actor != PlayerCharacter)
return;
if (Stimulus.Type != UAISense::GetSenseID<UAISense_Sight>())
return;
ANakedDesireCharacter* SensedPlayer = Cast<ANakedDesireCharacter>(Actor);
if (!SensedPlayer)
return;
PlayerCharacter = SensedPlayer;
const bool bSensed = Stimulus.WasSuccessfullySensed();
if (bSensed == bCurrentlyObserving)
return;
+1 -10
View File
@@ -7,8 +7,6 @@
#include "Perception/AIPerceptionTypes.h"
#include "NPCAIController.generated.h"
class ANakedDesireGameMode;
class UNavigationSystemV1;
class ANakedDesireCharacter;
UCLASS()
@@ -19,20 +17,13 @@ class NAKEDDESIRE_API ANPCAIController : public ADetourCrowdAIController
UPROPERTY()
ANakedDesireCharacter* PlayerCharacter = nullptr;
UPROPERTY()
const UNavigationSystemV1* NavigationSystem = nullptr;
UPROPERTY()
ANakedDesireGameMode* GameMode = nullptr;
UPROPERTY(EditDefaultsOnly)
UBehaviorTree* BehaviorTreeAsset = nullptr;
bool bCurrentlyObserving = false;
public:
UFUNCTION(BlueprintCallable)
void SetShouldReactToPlayer(bool Value);
ANPCAIController();
protected:
UFUNCTION()
-58
View File
@@ -1,58 +0,0 @@
// © 2025 Naked People Team. All Rights Reserved.
#include "NPCSpawner.h"
#include "NPC.h"
#include "Kismet/GameplayStatics.h"
#include "NakedDesire/Global/NakedDesireGameMode.h"
ANPCSpawner::ANPCSpawner()
{
PrimaryActorTick.bCanEverTick = false;
}
void ANPCSpawner::BeginPlay()
{
Super::BeginPlay();
PlayerCharacter = UGameplayStatics::GetPlayerCharacter(GetWorld(), 0);
FTimerHandle TimerHandle;
const int32 RandomDelay = FMath::RandRange(5, 30);
GetWorldTimerManager().SetTimer(TimerHandle, this, &ANPCSpawner::OnTimerTick, 30, true, RandomDelay);
OnTimerTick();
if (AGameModeBase* CurrentGameMode = UGameplayStatics::GetGameMode(GetWorld()))
{
GameMode = Cast<ANakedDesireGameMode>(CurrentGameMode);
}
}
void ANPCSpawner::OnTimerTick()
{
if (!PlayerCharacter || !GameMode)
{
return;
}
const bool IsPlayerClose = FVector::Dist(PlayerCharacter->GetActorLocation(), GetActorLocation()) < 5000;
const FTimecode CurrentTime = GameMode->GetCurrentTime();
const bool IsDay = CurrentTime.Hours >= 9.0f && CurrentTime.Hours < 21.00f;
const bool CanSpawnMore = IsDay ? NPCs.Num() < MaxCountDay : NPCs.Num() < MaxCountNight;
if (CanSpawnMore && PlayerCharacter && IsPlayerClose && (FMath::RandBool() && !AlwaysSpawn))
{
FActorSpawnParameters SpawnParameters;
SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
const int RandomIndex = FMath::RandRange(0, NPCClasses.Num() - 1);
ANPC* NewNPC = GetWorld()->SpawnActor<ANPC>(NPCClasses[RandomIndex], GetActorLocation(), GetActorRotation(), SpawnParameters);
NewNPC->OnDestroyed.AddUObject(this, &ANPCSpawner::OnNPCDestroyed);
NPCs.Add(NewNPC);
}
}
void ANPCSpawner::OnNPCDestroyed(ANPC* NPC)
{
NPCs.Remove(NPC);
}
-49
View File
@@ -1,49 +0,0 @@
// © 2025 Naked People Team. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "NPCSpawner.generated.h"
class ANakedDesireGameMode;
class ANPC;
UCLASS()
class NAKEDDESIRE_API ANPCSpawner : public AActor
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly)
TArray<TSubclassOf<ANPC>> NPCClasses;
UPROPERTY(EditAnywhere)
bool AlwaysSpawn = false;
UPROPERTY()
ACharacter* PlayerCharacter = nullptr;
bool IsPlayerInRange = false;
UPROPERTY()
ANakedDesireGameMode* GameMode = nullptr;
UPROPERTY()
TArray<ANPC*> NPCs;
UPROPERTY(EditAnywhere, meta = (ClampMin = 1, ClampMax = 30, UIMin = 1, UIMax = 30))
int MaxCountDay = 10;
UPROPERTY(EditAnywhere, meta = (ClampMin = 1, ClampMax = 30, UIMin = 1, UIMax = 30))
int MaxCountNight = 5;
public:
ANPCSpawner();
protected:
virtual void BeginPlay() override;
private:
void OnTimerTick();
void OnNPCDestroyed(ANPC* NPC);
};
@@ -1,11 +0,0 @@
// © 2025 Naked People Team. All Rights Reserved.
#include "NPCTargetLocation.h"
// Sets default values
ANPCTargetLocation::ANPCTargetLocation()
{
PrimaryActorTick.bCanEverTick = false;
}
@@ -1,16 +0,0 @@
// © 2025 Naked People Team. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "NPCTargetLocation.generated.h"
UCLASS()
class NAKEDDESIRE_API ANPCTargetLocation : public AActor
{
GENERATED_BODY()
public:
ANPCTargetLocation();
};