mirror of
https://github.com/Ed94/Cog.git
synced 2026-08-05 15:18:47 +00:00
Add behavior tree window
This commit is contained in:
Binary file not shown.
@@ -114,13 +114,13 @@ void UCogEngineWindow_Skeleton::RenderContent()
|
|||||||
ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, FCogWindowWidgets::GetFontWidth());
|
ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, FCogWindowWidgets::GetFontWidth());
|
||||||
|
|
||||||
HoveredBoneIndex = INDEX_NONE;
|
HoveredBoneIndex = INDEX_NONE;
|
||||||
DrawBoneEntry(0, false);
|
RenderBoneEntry(0, false);
|
||||||
|
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
void UCogEngineWindow_Skeleton::DrawBoneEntry(int32 BoneIndex, bool OpenAllChildren)
|
void UCogEngineWindow_Skeleton::RenderBoneEntry(int32 BoneIndex, bool OpenAllChildren)
|
||||||
{
|
{
|
||||||
if (BonesInfos.IsValidIndex(BoneIndex) == false)
|
if (BonesInfos.IsValidIndex(BoneIndex) == false)
|
||||||
{
|
{
|
||||||
@@ -202,6 +202,7 @@ void UCogEngineWindow_Skeleton::DrawBoneEntry(int32 BoneIndex, bool OpenAllChild
|
|||||||
// Checkbox
|
// Checkbox
|
||||||
//------------------------
|
//------------------------
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
FCogWindowWidgets::PushStyleCompact();
|
||||||
if (ImGui::Checkbox("##Visible", &BoneInfo.ShowBone))
|
if (ImGui::Checkbox("##Visible", &BoneInfo.ShowBone))
|
||||||
{
|
{
|
||||||
if (IsControlDown)
|
if (IsControlDown)
|
||||||
@@ -217,6 +218,7 @@ void UCogEngineWindow_Skeleton::DrawBoneEntry(int32 BoneIndex, bool OpenAllChild
|
|||||||
BoneInfo.ShowTrajectory = false;
|
BoneInfo.ShowTrajectory = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FCogWindowWidgets::PopStyleCompact();
|
||||||
|
|
||||||
const bool HasCustomVisiblity = BoneInfo.ShowName || BoneInfo.ShowAxes || BoneInfo.ShowLocalVelocity || BoneInfo.ShowTrajectory;
|
const bool HasCustomVisiblity = BoneInfo.ShowName || BoneInfo.ShowAxes || BoneInfo.ShowLocalVelocity || BoneInfo.ShowTrajectory;
|
||||||
if (HasCustomVisiblity)
|
if (HasCustomVisiblity)
|
||||||
@@ -239,13 +241,13 @@ void UCogEngineWindow_Skeleton::DrawBoneEntry(int32 BoneIndex, bool OpenAllChild
|
|||||||
{
|
{
|
||||||
for (int32 ChildIndex : BoneInfo.Children)
|
for (int32 ChildIndex : BoneInfo.Children)
|
||||||
{
|
{
|
||||||
DrawBoneEntry(ChildIndex, OpenAllChildren);
|
RenderBoneEntry(ChildIndex, OpenAllChildren);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShowNode)
|
if (ShowNode)
|
||||||
{
|
{
|
||||||
if (OpenChildren && ShowNode)
|
if (OpenChildren)
|
||||||
{
|
{
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ protected:
|
|||||||
virtual void OnSelectionChanged(AActor* OldSelection, AActor* NewSelection) override;
|
virtual void OnSelectionChanged(AActor* OldSelection, AActor* NewSelection) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DrawBoneEntry(int32 BoneIndex, bool OpenAllChildren);
|
void RenderBoneEntry(int32 BoneIndex, bool OpenAllChildren);
|
||||||
void SetChildrenVisibility(int32 BoneIndex, bool IsVisible);
|
void SetChildrenVisibility(int32 BoneIndex, bool IsVisible);
|
||||||
void DrawSkeleton();
|
void DrawSkeleton();
|
||||||
void RefreshSkeleton();
|
void RefreshSkeleton();
|
||||||
|
|||||||
@@ -0,0 +1,227 @@
|
|||||||
|
#include "CogAIWindow_BehaviorTree.h"
|
||||||
|
|
||||||
|
#include "AIController.h"
|
||||||
|
#include "BehaviorTree/BehaviorTree.h"
|
||||||
|
#include "BehaviorTree/BTCompositeNode.h"
|
||||||
|
#include "BehaviorTree/BTNode.h"
|
||||||
|
#include "BehaviorTree/Tasks/BTTask_Wait.h"
|
||||||
|
#include "BrainComponent.h"
|
||||||
|
#include "CogWindowWidgets.h"
|
||||||
|
#include "GameFramework/Pawn.h"
|
||||||
|
#include "imgui_internal.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void UCogAIWindow_BehaviorTree::RenderHelp()
|
||||||
|
{
|
||||||
|
ImGui::Text(
|
||||||
|
"This window displays the behavior tree of the selected actor. "
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
UCogAIWindow_BehaviorTree::UCogAIWindow_BehaviorTree()
|
||||||
|
{
|
||||||
|
bHasMenu = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void UCogAIWindow_BehaviorTree::RenderContent()
|
||||||
|
{
|
||||||
|
Super::RenderContent();
|
||||||
|
|
||||||
|
|
||||||
|
if (ImGui::BeginMenuBar())
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Options"))
|
||||||
|
{
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
FCogWindowWidgets::MenuSearchBar(Filter);
|
||||||
|
|
||||||
|
ImGui::EndMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
AActor* Selection = GetSelection();
|
||||||
|
if (Selection == nullptr)
|
||||||
|
{
|
||||||
|
ImGui::TextDisabled("No Selection");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
APawn* Pawn = Cast<APawn>(Selection);
|
||||||
|
if (Pawn == nullptr)
|
||||||
|
{
|
||||||
|
ImGui::TextDisabled("Not a pawn");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AAIController* AIController = Cast<AAIController>(Pawn->Controller);
|
||||||
|
if (AIController == nullptr)
|
||||||
|
{
|
||||||
|
ImGui::TextDisabled("No AIController");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UBehaviorTreeComponent* BehaviorTreeComponent = Cast<UBehaviorTreeComponent>(AIController->GetBrainComponent());
|
||||||
|
if (BehaviorTreeComponent == nullptr)
|
||||||
|
{
|
||||||
|
ImGui::TextDisabled("No BrainComponent");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UBehaviorTree* CurrentTree = BehaviorTreeComponent->GetCurrentTree();
|
||||||
|
if (CurrentTree == nullptr)
|
||||||
|
{
|
||||||
|
ImGui::TextDisabled("No Current Tree");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
// If we use the current tree root node it doesn't seem to be the one instanced.
|
||||||
|
// Not sure if there is a better way to access it, but we find the root node from
|
||||||
|
// the current active node. Then we will be able to check if the drawn nodes is
|
||||||
|
// parent of the active node to display it active.
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
const UBTNode* RootNodeInstanced = nullptr;
|
||||||
|
for (const UBTNode* ParentNode = BehaviorTreeComponent->GetActiveNode(); ParentNode != nullptr; ParentNode = ParentNode->GetParentNode())
|
||||||
|
{
|
||||||
|
RootNodeInstanced = ParentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RootNodeInstanced != nullptr)
|
||||||
|
{
|
||||||
|
RenderNode(BehaviorTreeComponent, RootNodeInstanced, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void UCogAIWindow_BehaviorTree::RenderNode(UBehaviorTreeComponent* BehaviorTreeComponent, const UBTNode* Node, bool OpenAllChildren)
|
||||||
|
{
|
||||||
|
const char* NodeName = TCHAR_TO_ANSI(*Node->GetNodeName());
|
||||||
|
const bool ShowNode = Filter.PassFilter(NodeName);
|
||||||
|
|
||||||
|
const UBTCompositeNode* CompositeNode = Cast<UBTCompositeNode>(Node);
|
||||||
|
|
||||||
|
bool IsActive = false;
|
||||||
|
for (const UBTNode* ActiveParentNode = BehaviorTreeComponent->GetActiveNode(); ActiveParentNode != nullptr; ActiveParentNode = ActiveParentNode->GetParentNode())
|
||||||
|
{
|
||||||
|
if (Node == ActiveParentNode)
|
||||||
|
{
|
||||||
|
IsActive = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenChildren = false;
|
||||||
|
|
||||||
|
if (ShowNode)
|
||||||
|
{
|
||||||
|
ImGui::PushID(Node);
|
||||||
|
|
||||||
|
if (OpenAllChildren)
|
||||||
|
{
|
||||||
|
ImGui::SetNextItemOpen(true, ImGuiCond_Always);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// TreeNode
|
||||||
|
//------------------------
|
||||||
|
const bool HasChildren = CompositeNode != nullptr && CompositeNode->GetChildrenNum() > 0;
|
||||||
|
if (HasChildren && Filter.IsActive() == false)
|
||||||
|
{
|
||||||
|
OpenChildren = ImGui::TreeNodeEx("##Node", ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_SpanFullWidth);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui::TreeNodeEx("##Node", ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_SpanFullWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool IsControlDown = ImGui::GetCurrentContext()->IO.KeyCtrl;
|
||||||
|
if (ImGui::IsItemClicked(ImGuiMouseButton_Left) && IsControlDown)
|
||||||
|
{
|
||||||
|
OpenAllChildren = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// ContextMenu
|
||||||
|
//------------------------
|
||||||
|
if (ImGui::BeginPopupContextItem())
|
||||||
|
{
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// Tooltip
|
||||||
|
//------------------------
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::BeginDisabled();
|
||||||
|
ImGui::Text(TCHAR_TO_ANSI(*Node->GetStaticDescription()));
|
||||||
|
|
||||||
|
if (const UBTTask_Wait* Wait = Cast<UBTTask_Wait>(Node))
|
||||||
|
{
|
||||||
|
ImGui::Text("Wait: %0.2fs", Wait->WaitTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// Checkbox
|
||||||
|
//------------------------
|
||||||
|
ImGui::SameLine();
|
||||||
|
FCogWindowWidgets::PushStyleCompact();
|
||||||
|
if (IsActive == false)
|
||||||
|
{
|
||||||
|
ImGui::BeginDisabled();
|
||||||
|
}
|
||||||
|
bool DrawActive = IsActive;
|
||||||
|
ImGui::Checkbox("##Active", &DrawActive);
|
||||||
|
|
||||||
|
if (IsActive == false)
|
||||||
|
{
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
}
|
||||||
|
FCogWindowWidgets::PopStyleCompact();
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// Name
|
||||||
|
//------------------------
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImVec4 NameColor = IsActive ? ImVec4(0.0f, 1.0f, 0.0f, 1.0f) : ImVec4(1.0f, 1.0f, 1.0f, 0.6f);
|
||||||
|
ImGui::TextColored(NameColor, "%s", NodeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// Children
|
||||||
|
//------------------------
|
||||||
|
if (OpenChildren || Filter.IsActive())
|
||||||
|
{
|
||||||
|
if (CompositeNode != nullptr)
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < CompositeNode->GetChildrenNum(); ++i)
|
||||||
|
{
|
||||||
|
const UBTNode* ChildNode = CompositeNode->GetChildNode(i);
|
||||||
|
RenderNode(BehaviorTreeComponent, ChildNode, OpenAllChildren);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ShowNode)
|
||||||
|
{
|
||||||
|
if (OpenChildren)
|
||||||
|
{
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -50,35 +50,35 @@ void UCogAIWindow_Blackboard::RenderContent()
|
|||||||
APawn* Pawn = Cast<APawn>(Selection);
|
APawn* Pawn = Cast<APawn>(Selection);
|
||||||
if (Pawn == nullptr)
|
if (Pawn == nullptr)
|
||||||
{
|
{
|
||||||
ImGui::TextDisabled("Selection is not a pawn");
|
ImGui::TextDisabled("Not a pawn");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AAIController* AIController = Cast<AAIController>(Pawn->Controller);
|
AAIController* AIController = Cast<AAIController>(Pawn->Controller);
|
||||||
if (AIController == nullptr)
|
if (AIController == nullptr)
|
||||||
{
|
{
|
||||||
ImGui::TextDisabled("Selection has no AIController");
|
ImGui::TextDisabled("No AIController");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UBrainComponent* Brain = AIController->GetBrainComponent();
|
UBrainComponent* BehaviorTree = AIController->GetBrainComponent();
|
||||||
if (Brain == nullptr)
|
if (BehaviorTree == nullptr)
|
||||||
{
|
{
|
||||||
ImGui::TextDisabled("Selection controller has no BrainComponent");
|
ImGui::TextDisabled("No BrainComponent");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UBlackboardComponent* Blackboard = Brain->GetBlackboardComponent();
|
UBlackboardComponent* Blackboard = BehaviorTree->GetBlackboardComponent();
|
||||||
if (Blackboard == nullptr)
|
if (Blackboard == nullptr)
|
||||||
{
|
{
|
||||||
ImGui::TextDisabled("Selection controller has no BlackboardComponent");
|
ImGui::TextDisabled("No BlackboardComponent");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UBlackboardData* BlackboardAsset = Blackboard->GetBlackboardAsset();
|
UBlackboardData* BlackboardAsset = Blackboard->GetBlackboardAsset();
|
||||||
if (BlackboardAsset == nullptr)
|
if (BlackboardAsset == nullptr)
|
||||||
{
|
{
|
||||||
ImGui::TextDisabled("BlackboardComponent has no BlackboardAsset");
|
ImGui::TextDisabled("No BlackboardAsset");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "CogWindow.h"
|
||||||
|
#include "CogAIWindow_BehaviorTree.generated.h"
|
||||||
|
|
||||||
|
class UBehaviorTreeComponent;
|
||||||
|
class UBTNode;
|
||||||
|
|
||||||
|
UCLASS(Config = Cog)
|
||||||
|
class COGAI_API UCogAIWindow_BehaviorTree : public UCogWindow
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UCogAIWindow_BehaviorTree();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void RenderHelp();
|
||||||
|
|
||||||
|
virtual void RenderContent() override;
|
||||||
|
|
||||||
|
virtual void RenderNode(UBehaviorTreeComponent* BehaviorTreeComponent, const UBTNode* Node, bool OpenAllChildren);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ImGuiTextFilter Filter;
|
||||||
|
};
|
||||||
@@ -4,9 +4,6 @@
|
|||||||
#include "CogWindow.h"
|
#include "CogWindow.h"
|
||||||
#include "CogAIWindow_Blackboard.generated.h"
|
#include "CogAIWindow_Blackboard.generated.h"
|
||||||
|
|
||||||
namespace FBlackboard { typedef uint8 FKey; }
|
|
||||||
class UBlackboardData;
|
|
||||||
|
|
||||||
UCLASS(Config = Cog)
|
UCLASS(Config = Cog)
|
||||||
class COGAI_API UCogAIWindow_Blackboard : public UCogWindow
|
class COGAI_API UCogAIWindow_Blackboard : public UCogWindow
|
||||||
{
|
{
|
||||||
@@ -28,5 +25,4 @@ private:
|
|||||||
bool bSortByName = true;
|
bool bSortByName = true;
|
||||||
|
|
||||||
ImGuiTextFilter Filter;
|
ImGuiTextFilter Filter;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "CogAbilityWindow_Pools.h"
|
#include "CogAbilityWindow_Pools.h"
|
||||||
#include "CogAbilityWindow_Tags.h"
|
#include "CogAbilityWindow_Tags.h"
|
||||||
#include "CogAbilityWindow_Tweaks.h"
|
#include "CogAbilityWindow_Tweaks.h"
|
||||||
|
#include "CogAIWindow_BehaviorTree.h"
|
||||||
#include "CogAIWindow_Blackboard.h"
|
#include "CogAIWindow_Blackboard.h"
|
||||||
#include "CogDebugDrawImGui.h"
|
#include "CogDebugDrawImGui.h"
|
||||||
#include "CogDebugPlot.h"
|
#include "CogDebugPlot.h"
|
||||||
@@ -206,10 +207,8 @@ void ACogSampleGameState::InitializeCog()
|
|||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
// AI
|
// AI
|
||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
//const UCogAIDataAsset* InputAsset = GetFirstAssetByClass<UCogAIDataAsset>();
|
CogWindowManager->CreateWindow<UCogAIWindow_BehaviorTree>("AI.Behavior Tree");
|
||||||
|
CogWindowManager->CreateWindow<UCogAIWindow_Blackboard>("AI.Blackboard");
|
||||||
UCogAIWindow_Blackboard* BlackboardWindow = CogWindowManager->CreateWindow<UCogAIWindow_Blackboard>("AI.Blackboard");
|
|
||||||
//BlackboardWindow->SetAsset(InputAsset);
|
|
||||||
|
|
||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
// Input
|
// Input
|
||||||
|
|||||||
Reference in New Issue
Block a user