Added Comments to GOAP Functions
This commit is contained in:
parent
4639a4d1ac
commit
2b43f174a2
@ -3,6 +3,11 @@
|
||||
|
||||
#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)
|
||||
{
|
||||
for (TPair<FString, int> PreCondition : PreConditions)
|
||||
@ -15,6 +20,11 @@ bool UGOAPAction::CheckPreConditions(UWorldState* WorldState)
|
||||
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* NewWorldState = NewObject<UWorldState>();
|
||||
@ -29,6 +39,10 @@ UWorldState* UGOAPAction::ApplyEffects(UWorldState* WorldState)
|
||||
return NewWorldState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Performs the action
|
||||
* @return A map of the effects of the action
|
||||
*/
|
||||
TMap<FString, int> UGOAPAction::Perform()
|
||||
{
|
||||
return Effects;
|
||||
|
@ -32,10 +32,18 @@ void UGOAPAgent::BeginPlay()
|
||||
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; });
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 bFoundAPlan = false;
|
||||
@ -48,12 +56,24 @@ bool UGOAPAgent::BuildActionGraph(UActionNode* Parent, TArray<UActionNode*>& Suc
|
||||
UActionNode* NewNode = NewObject<UActionNode>();
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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*> 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);
|
||||
return ActionPlan;
|
||||
}
|
||||
|
@ -534,7 +534,7 @@ void ATurnBaseCombatV2::StealButtonOnClick()
|
||||
{
|
||||
StealButton->SetIsEnabled(false);
|
||||
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; });
|
||||
for (int* Resource : Resources)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user