Add runtime values in the behavior tree window

Sort blackboard by name
This commit is contained in:
Arnaud Jamin
2023-10-17 12:35:56 -04:00
parent 4e342c8fce
commit ead94dffe6
5 changed files with 123 additions and 58 deletions
Binary file not shown.
@@ -92,30 +92,20 @@ void UCogAIWindow_BehaviorTree::RenderContent()
if (RootNodeInstanced != nullptr)
{
RenderNode(BehaviorTreeComponent, RootNodeInstanced, false);
RenderNode(*BehaviorTreeComponent, const_cast<UBTNode*>(RootNodeInstanced), false);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAIWindow_BehaviorTree::RenderNode(UBehaviorTreeComponent* BehaviorTreeComponent, const UBTNode* Node, bool OpenAllChildren)
void UCogAIWindow_BehaviorTree::RenderNode(UBehaviorTreeComponent& BehaviorTreeComponent, UBTNode* Node, bool OpenAllChildren)
{
FString NodeNameStr;
if (const UBTTask_BlueprintBase* Wait = Cast<UBTTask_BlueprintBase>(Node))
{
NodeNameStr = Node->GetNodeName();
}
else
{
NodeNameStr = Node->GetStaticDescription();
}
const char* NodeName = TCHAR_TO_ANSI(*NodeNameStr);
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())
for (const UBTNode* ActiveParentNode = BehaviorTreeComponent.GetActiveNode(); ActiveParentNode != nullptr; ActiveParentNode = ActiveParentNode->GetParentNode())
{
if (Node == ActiveParentNode)
{
@@ -171,11 +161,66 @@ void UCogAIWindow_BehaviorTree::RenderNode(UBehaviorTreeComponent* BehaviorTreeC
//------------------------
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::BeginDisabled();
ImGui::Text(NodeName);
ImGui::EndDisabled();
ImGui::EndTooltip();
FCogWindowWidgets::BeginTableTooltip();
if (ImGui::BeginTable("Effect", 2, ImGuiTableFlags_Borders))
{
ImGui::TableSetupColumn("Property");
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
const ImVec4 TextColor(1.0f, 1.0f, 1.0f, 0.5f);
//------------------------
// Name
//------------------------
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextColored(TextColor, "Name");
ImGui::TableNextColumn();
ImGui::Text("%s", NodeName);
//------------------------
// Static Description
//------------------------
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextColored(TextColor, "Description");
ImGui::TableNextColumn();
ImGui::Text("%s", TCHAR_TO_ANSI(*Node->GetStaticDescription()));
//------------------------
// Runtime Values
//------------------------
TArray<FString> RunTimeValues;
uint8* NodeMemory = BehaviorTreeComponent.GetNodeMemory(Node, BehaviorTreeComponent.GetActiveInstanceIdx());
Node->DescribeRuntimeValues(BehaviorTreeComponent, NodeMemory, EBTDescriptionVerbosity::Detailed, RunTimeValues);
for (const FString& RuntimeValue : RunTimeValues)
{
ImGui::TableNextRow();
FString Left, Right;
if (RuntimeValue.Split(TEXT(": "), &Left, &Right))
{
ImGui::TableNextColumn();
ImGui::TextColored(TextColor, TCHAR_TO_ANSI(*Left));
ImGui::TableNextColumn();
ImGui::Text("%s", TCHAR_TO_ANSI(*Right));
}
else
{
ImGui::TableNextColumn();
ImGui::TextColored(TextColor, "Value");
ImGui::TableNextColumn();
ImGui::Text(TCHAR_TO_ANSI(*RuntimeValue));
}
}
ImGui::EndTable();
}
FCogWindowWidgets::EndTableTooltip();
}
//------------------------
@@ -213,7 +258,7 @@ void UCogAIWindow_BehaviorTree::RenderNode(UBehaviorTreeComponent* BehaviorTreeC
{
for (int32 i = 0; i < CompositeNode->GetChildrenNum(); ++i)
{
const UBTNode* ChildNode = CompositeNode->GetChildNode(i);
UBTNode* ChildNode = CompositeNode->GetChildNode(i);
RenderNode(BehaviorTreeComponent, ChildNode, OpenAllChildren);
}
}
@@ -82,6 +82,29 @@ void UCogAIWindow_Blackboard::RenderContent()
return;
}
TArray<const FBlackboardEntry*> Keys;
uint8 Offset = 0;
for (UBlackboardData* It = BlackboardAsset; It; It = It->Parent)
{
for (int32 KeyID = 0; KeyID < It->Keys.Num(); KeyID++)
{
if (const FBlackboardEntry* Key = BlackboardAsset->GetKey(KeyID))
{
Keys.Add(Key);
}
}
Offset += It->Keys.Num();
}
if (bSortByName)
{
Keys.Sort([](const FBlackboardEntry& Key1, const FBlackboardEntry& Key2)
{
return Key1.EntryName.Compare(Key1.EntryName) < 0;
});
}
if (ImGui::BeginTable("Blackboard", 3, ImGuiTableFlags_SizingFixedFit
| ImGuiTableFlags_Resizable
| ImGuiTableFlags_NoBordersInBodyUntilResize
@@ -101,39 +124,43 @@ void UCogAIWindow_Blackboard::RenderContent()
const FString CommonTypePrefix = UBlackboardKeyType::StaticClass()->GetName().AppendChar(TEXT('_'));
uint8 Offset = 0;
for (UBlackboardData* It = BlackboardAsset; It; It = It->Parent)
for (int32 KeyID = 0; KeyID < Keys.Num(); ++KeyID)
{
for (int32 KeyID = 0; KeyID < It->Keys.Num(); KeyID++)
const FBlackboardEntry* Key = Keys[KeyID];
if (Key == nullptr)
{
const FBlackboardEntry* Key = BlackboardAsset->GetKey(KeyID);
if (Key == nullptr)
{
continue;
}
const char* KeyName = TCHAR_TO_ANSI(*Key->EntryName.ToString());
if (Filter.PassFilter(KeyName) == false)
{
continue;
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
const FString FullKeyType = Key->KeyType ? GetNameSafe(Key->KeyType->GetClass()) : FString();
const FString DescKeyType = FullKeyType.StartsWith(CommonTypePrefix) ? FullKeyType.RightChop(CommonTypePrefix.Len()) : FullKeyType;
ImGui::Text("%s", TCHAR_TO_ANSI(*DescKeyType));
ImGui::TableNextColumn();
ImGui::Text("%s", KeyName);
ImGui::TableNextColumn();
const uint8* ValueData = Blackboard->GetKeyRawData(KeyID);
FString ValueDesc = Key->KeyType && ValueData ? *(Key->KeyType->WrappedDescribeValue(*Blackboard, ValueData)) : TEXT("Empty");
ImGui::Text("%s", TCHAR_TO_ANSI(*ValueDesc));
continue;
}
Offset += It->Keys.Num();
const char* KeyName = TCHAR_TO_ANSI(*Key->EntryName.ToString());
if (Filter.PassFilter(KeyName) == false)
{
continue;
}
ImGui::TableNextRow();
//------------------------
// Type
//------------------------
ImGui::TableNextColumn();
const FString FullKeyType = Key->KeyType ? GetNameSafe(Key->KeyType->GetClass()) : FString();
const FString DescKeyType = FullKeyType.StartsWith(CommonTypePrefix) ? FullKeyType.RightChop(CommonTypePrefix.Len()) : FullKeyType;
ImGui::Text("%s", TCHAR_TO_ANSI(*DescKeyType));
//------------------------
// Name
//------------------------
ImGui::TableNextColumn();
ImGui::Text("%s", KeyName);
//------------------------
// Value
//------------------------
ImGui::TableNextColumn();
const uint8* ValueData = Blackboard->GetKeyRawData(KeyID);
FString ValueDesc = Key->KeyType && ValueData ? *(Key->KeyType->WrappedDescribeValue(*Blackboard, ValueData)) : TEXT("Empty");
ImGui::Text("%s", TCHAR_TO_ANSI(*ValueDesc));
}
ImGui::EndTable();
@@ -22,7 +22,7 @@ protected:
virtual void RenderContent() override;
virtual void RenderNode(UBehaviorTreeComponent* BehaviorTreeComponent, const UBTNode* Node, bool OpenAllChildren);
virtual void RenderNode(UBehaviorTreeComponent& BehaviorTreeComponent, UBTNode* Node, bool OpenAllChildren);
private:
-7
View File
@@ -1,20 +1,15 @@
- CogImGui: Add a way to create and override CogImguiwidget
- CogImGui: Try to find a global solution to prevent crash when breaking in a blueprint from an imgui action (reset the stack)
- CogDebug: Add log category description
- CogWindow: Add reset window position menu item or reset layout (window can get far away)
- CogWindow: Try to remove CogWindow dependency to cogimgui. Should only depends on imgui (currently use setdpiscale of cogimgui)
- CogWindow: Add reset window position menu item or reset layout (window can get far away)
- CogEngine: Save selection window settings (current actor and category)
- CogEngine: More stats in the stats window
- CogEngine: Overlay mode of stats.
- CogEngine: Stat main menu widget could have a tooltip on each stat with a control to change set the emulation (FPS, Ping, Packetloss)
- CogEngine: Skeleton window selectable have wrong height
- CogEngine: Property grid
- CogEngine: user settings
- CogInput: Add multiple IMC on the input data asset. Maybe propose a current imc
- CogInput: Add mouse over highlight on the buttons of the gamepad window
@@ -24,5 +19,3 @@
- CogSample: Add a custom window in sample (changing the character faction)
- CogSample: Create more abilities
- CogSample: Add area of effects in the level
- CogAI: Create a CogAI project with windows for BT and other AI tools