Added Comments to GOAP Functions
This commit is contained in:
parent
4639a4d1ac
commit
2b43f174a2
@ -3,6 +3,11 @@
|
|||||||
|
|
||||||
#include "GOAPAction.h"
|
#include "GOAPAction.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if the preconditions are met in the world state given
|
||||||
|
* @param WorldState A pointer to the world state to check
|
||||||
|
* @return True if the preconditions are met and false if not
|
||||||
|
*/
|
||||||
bool UGOAPAction::CheckPreConditions(UWorldState* WorldState)
|
bool UGOAPAction::CheckPreConditions(UWorldState* WorldState)
|
||||||
{
|
{
|
||||||
for (TPair<FString, int> PreCondition : PreConditions)
|
for (TPair<FString, int> PreCondition : PreConditions)
|
||||||
@ -15,6 +20,11 @@ bool UGOAPAction::CheckPreConditions(UWorldState* WorldState)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Applies the effects of the action to the world state given
|
||||||
|
* @param WorldState A pointer to the world state to apply the effects to
|
||||||
|
* @return A pointer to the new world state
|
||||||
|
*/
|
||||||
UWorldState* UGOAPAction::ApplyEffects(UWorldState* WorldState)
|
UWorldState* UGOAPAction::ApplyEffects(UWorldState* WorldState)
|
||||||
{
|
{
|
||||||
UWorldState* NewWorldState = NewObject<UWorldState>();
|
UWorldState* NewWorldState = NewObject<UWorldState>();
|
||||||
@ -29,6 +39,10 @@ UWorldState* UGOAPAction::ApplyEffects(UWorldState* WorldState)
|
|||||||
return NewWorldState;
|
return NewWorldState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Performs the action
|
||||||
|
* @return A map of the effects of the action
|
||||||
|
*/
|
||||||
TMap<FString, int> UGOAPAction::Perform()
|
TMap<FString, int> UGOAPAction::Perform()
|
||||||
{
|
{
|
||||||
return Effects;
|
return Effects;
|
||||||
|
@ -32,10 +32,18 @@ void UGOAPAgent::BeginPlay()
|
|||||||
AvailableActions.Add(Action);
|
AvailableActions.Add(Action);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Sort AvailableActions by cost
|
//Sorts AvailableActions by cost to optimise the search by choosing the cheapest action first
|
||||||
AvailableActions.Sort([](const UGOAPAction& A, const UGOAPAction& B) { return A.ActionCost < B.ActionCost; });
|
AvailableActions.Sort([](const UGOAPAction& A, const UGOAPAction& B) { return A.ActionCost < B.ActionCost; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Recursive function to build a tree of possible actions
|
||||||
|
* @param Parent The parent node containing the previous action or null if this is the root node
|
||||||
|
* @param SuccessfulLeaves The array of nodes that lead to a successful goal state
|
||||||
|
* @param WorldState The state of the world with it's applicable effects applied
|
||||||
|
* @param AgentGoals The goals of the agent
|
||||||
|
* @return True if a plan was found and false if not
|
||||||
|
*/
|
||||||
bool UGOAPAgent::BuildActionGraph(UActionNode* Parent, TArray<UActionNode*>& SuccessfulLeaves, UWorldState* WorldState, TMap<FString, int> AgentGoals)
|
bool UGOAPAgent::BuildActionGraph(UActionNode* Parent, TArray<UActionNode*>& SuccessfulLeaves, UWorldState* WorldState, TMap<FString, int> AgentGoals)
|
||||||
{
|
{
|
||||||
bool bFoundAPlan = false;
|
bool bFoundAPlan = false;
|
||||||
@ -48,12 +56,24 @@ bool UGOAPAgent::BuildActionGraph(UActionNode* Parent, TArray<UActionNode*>& Suc
|
|||||||
UActionNode* NewNode = NewObject<UActionNode>();
|
UActionNode* NewNode = NewObject<UActionNode>();
|
||||||
NewNode->Init(Parent, Action, NewWorldState, Parent->Cost + Action->ActionCost);
|
NewNode->Init(Parent, Action, NewWorldState, Parent->Cost + Action->ActionCost);
|
||||||
|
|
||||||
if (NewWorldState->State["PlayerHealth"] <= 0)
|
//Check if the new state meets the agent's goals
|
||||||
|
bool bMetGoals = true;
|
||||||
|
for (TTuple<FString, int> Goal : AgentGoals)
|
||||||
|
{
|
||||||
|
if (NewWorldState->State[Goal.Key] > Goal.Value)
|
||||||
|
{
|
||||||
|
bMetGoals = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bMetGoals)
|
||||||
{
|
{
|
||||||
SuccessfulLeaves.Add(NewNode);
|
SuccessfulLeaves.Add(NewNode);
|
||||||
bFoundAPlan = true;
|
bFoundAPlan = true;
|
||||||
}
|
}
|
||||||
else if (!SeenStates.Contains(NewWorldState) && !bFoundAPlan)
|
|
||||||
|
//Check if the new state has been seen before and if a plan has been found otherwise recurse
|
||||||
|
if (!SeenStates.Contains(NewWorldState) && !bFoundAPlan)
|
||||||
{
|
{
|
||||||
SeenStates.Add(NewWorldState);
|
SeenStates.Add(NewWorldState);
|
||||||
TArray<UActionNode*> NewLeaves;
|
TArray<UActionNode*> NewLeaves;
|
||||||
@ -66,17 +86,6 @@ bool UGOAPAgent::BuildActionGraph(UActionNode* Parent, TArray<UActionNode*>& Suc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Log the plan
|
|
||||||
if (bFoundAPlan)
|
|
||||||
{
|
|
||||||
UE_LOG(LogTemp, Warning, TEXT("Found a plan!"));
|
|
||||||
// UActionNode* CurrentNode = SuccessfulLeaves[0];
|
|
||||||
// while (CurrentNode->Parent != nullptr)
|
|
||||||
// {
|
|
||||||
// UE_LOG(LogTemp, Warning, TEXT("%s"), *CurrentNode->Action->GetName());
|
|
||||||
// CurrentNode = CurrentNode->Parent;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
return bFoundAPlan;
|
return bFoundAPlan;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +97,13 @@ void UGOAPAgent::TickComponent(float DeltaTime, ELevelTick TickType, FActorCompo
|
|||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a plan of actions to achieve the agent's goals
|
||||||
|
* @param WorldState The current state of the world
|
||||||
|
* @param AgentGoals The goals of the agent
|
||||||
|
* @return An array of actions to achieve the agent's goals efficiently with it's current resources or
|
||||||
|
* an empty array if no plan was found
|
||||||
|
*/
|
||||||
TArray<UGOAPAction*> UGOAPAgent::Plan(UWorldState* WorldState, TMap<FString, int> AgentGoals)
|
TArray<UGOAPAction*> UGOAPAgent::Plan(UWorldState* WorldState, TMap<FString, int> AgentGoals)
|
||||||
{
|
{
|
||||||
TArray<UGOAPAction*> ActionPlan;
|
TArray<UGOAPAction*> ActionPlan;
|
||||||
@ -128,7 +144,7 @@ TArray<UGOAPAction*> UGOAPAgent::Plan(UWorldState* WorldState, TMap<FString, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Remove the first action as it is null due to being the root node
|
//Remove the first action as it's action is null due to being the root node
|
||||||
ActionPlan.RemoveAt(0);
|
ActionPlan.RemoveAt(0);
|
||||||
return ActionPlan;
|
return ActionPlan;
|
||||||
}
|
}
|
||||||
|
@ -534,7 +534,7 @@ void ATurnBaseCombatV2::StealButtonOnClick()
|
|||||||
{
|
{
|
||||||
StealButton->SetIsEnabled(false);
|
StealButton->SetIsEnabled(false);
|
||||||
ClearActionPlanWidget();
|
ClearActionPlanWidget();
|
||||||
TArray<int*> Resources = {&EnemyProbertiumResource, &EnemyEisResource, &EnemyAzosResource, &EnemyIroquoidResource};
|
TArray Resources = {&EnemyProbertiumResource, &EnemyEisResource, &EnemyAzosResource, &EnemyIroquoidResource};
|
||||||
Resources.Sort([](const int& A, const int& B) { return A > B; });
|
Resources.Sort([](const int& A, const int& B) { return A > B; });
|
||||||
for (int* Resource : Resources)
|
for (int* Resource : Resources)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user