Added NPC logic

This commit is contained in:
2026-06-01 22:04:31 +03:00
parent ce5e736472
commit 6bfa9f5396
37 changed files with 156 additions and 41 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.
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.
+1 -1
View File
@@ -1,4 +1,4 @@
# Development Plan # Development Plan
Working document for Naked Desire implementation. Tracks current state vs. the GDD (README.md) and the phased roadmap. Update this file as state changes — code is the source of truth, this file is the navigation chart. Working document for Naked Desire implementation. Tracks current state vs. the GDD (README.md) and the phased roadmap. Update this file as state changes — code is the source of truth, this file is the navigation chart.
+22 -4
View File
@@ -2,8 +2,12 @@
#include "NPC.h" #include "NPC.h"
#include "BrainComponent.h"
#include "NPCTypeDefinition.h" #include "NPCTypeDefinition.h"
#include "NPCAIController.h" #include "NPCAIController.h"
#include "NPCTargetLocation.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "Components/SkeletalMeshComponent.h" #include "Components/SkeletalMeshComponent.h"
#include "GameFramework/CharacterMovementComponent.h" #include "GameFramework/CharacterMovementComponent.h"
@@ -58,15 +62,26 @@ void ANPC::ActivateFromPool(const FVector& Location, const FRotator& Rotation)
Move->SetComponentTickEnabled(true); Move->SetComponentTickEnabled(true);
Move->SetMovementMode(MOVE_Walking); Move->SetMovementMode(MOVE_Walking);
} }
OnActivatedFromPool(); if (ANPCAIController* NPCController = Cast<ANPCAIController>(GetController()))
{
NPCController->RunCustomBehaviorTree();
NPCController->GetBlackboardComponent()->SetValueAsBool(TEXT("bHasReacted"), false);
}
} }
void ANPC::DeactivateToPool() void ANPC::DeactivateToPool()
{ {
// Drop any active observation so a pooled-out NPC stops contributing to the player's embarrassment. // Drop any active observation so a pooled-out NPC stops contributing to the player's embarrassment.
if (ANPCAIController* NPCController = Cast<ANPCAIController>(GetController())) if (ANPCAIController* NPCController = Cast<ANPCAIController>(GetController()))
{
NPCController->ClearObservation(); NPCController->ClearObservation();
if (UBrainComponent* Brain = NPCController->GetBrainComponent())
{
Brain->StopLogic(TEXT("Moved to pool"));
}
NPCController->ClearFocus(EAIFocusPriority::Default);
}
if (UCharacterMovementComponent* Move = GetCharacterMovement()) if (UCharacterMovementComponent* Move = GetCharacterMovement())
{ {
@@ -74,9 +89,12 @@ void ANPC::DeactivateToPool()
Move->DisableMovement(); Move->DisableMovement();
Move->SetComponentTickEnabled(false); Move->SetComponentTickEnabled(false);
} }
if (TargetLocationActor)
{
TargetLocationActor->Release(this);
}
SetActorHiddenInGame(true); SetActorHiddenInGame(true);
SetActorEnableCollision(false); SetActorEnableCollision(false);
OnDeactivatedToPool();
} }
+3 -5
View File
@@ -7,6 +7,7 @@
#include "NPCType.h" #include "NPCType.h"
#include "NPC.generated.h" #include "NPC.generated.h"
class ANPCTargetLocation;
class UNPCTypeDefinition; class UNPCTypeDefinition;
UCLASS() UCLASS()
@@ -44,9 +45,6 @@ public:
void DeactivateToPool(); void DeactivateToPool();
protected: protected:
UFUNCTION(BlueprintImplementableEvent, Category = "NPC") UPROPERTY(BlueprintReadWrite, Category = "NPC")
void OnActivatedFromPool(); TObjectPtr<ANPCTargetLocation> TargetLocationActor;
UFUNCTION(BlueprintImplementableEvent, Category = "NPC")
void OnDeactivatedToPool();
}; };
@@ -45,6 +45,11 @@ void ANPCAIController::ClearObservation()
} }
} }
void ANPCAIController::RunCustomBehaviorTree()
{
RunBehaviorTree(BehaviorTreeAsset);
}
float ANPCAIController::GetObservationWeight() const float ANPCAIController::GetObservationWeight() const
{ {
if (const ANPC* NPC = Cast<ANPC>(GetPawn())) if (const ANPC* NPC = Cast<ANPC>(GetPawn()))
+1
View File
@@ -27,6 +27,7 @@ public:
// Clears any active observation of the player (used on un-possess and when the NPC is pooled out). // Clears any active observation of the player (used on un-possess and when the NPC is pooled out).
void ClearObservation(); void ClearObservation();
void RunCustomBehaviorTree();
protected: protected:
UFUNCTION() UFUNCTION()
@@ -0,0 +1,29 @@
// © 2025 Naked People Team. All Rights Reserved.
#include "NPCTargetLocation.h"
#include "NPC.h"
ANPCTargetLocation::ANPCTargetLocation()
{
PrimaryActorTick.bCanEverTick = false;
}
bool ANPCTargetLocation::TryClaim(ANPC* InClaimant)
{
if (Claimant.IsValid() && Claimant.Get() != InClaimant)
return false;
Claimant = InClaimant;
return true;
}
void ANPCTargetLocation::Release(ANPC* Requester)
{
if (!Claimant.IsValid() || Claimant.Get() != Requester)
return;
Claimant = nullptr;
}
@@ -0,0 +1,31 @@
// © 2025 Naked People Team. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "NPCTargetLocation.generated.h"
class ANPC;
UCLASS()
class NAKEDDESIRE_API ANPCTargetLocation : public AActor
{
GENERATED_BODY()
public:
ANPCTargetLocation();
UFUNCTION(BlueprintCallable)
bool TryClaim(ANPC* InClaimant);
UFUNCTION(BlueprintPure)
bool IsClaimed() const { return Claimant.IsValid(); }
UFUNCTION(BlueprintCallable)
void Release(ANPC* Requester);
private:
UPROPERTY()
TWeakObjectPtr<ANPC> Claimant = nullptr;
};