Este guia técnico explora a construção dos painéis Hierarchy e Inspector em um editor de motor de jogo C++. Esses componentes são essenciais para gerenciar a hierarquia de objetos de jogo e editar propriedades em tempo real, utilizanod a biblioteca ImGui para a interface gráfica.
Importância dos Painéis Hierarchy e Inspector
No desenvolvimento de jogos, o painel Hierarchy exibe uma estrutura em árvore dos objetos na cena, permitindo gerenciar relações pai-filho. O painel Inspector habilita a visualização e modificação de atributos do objeto selecionado, como transformações e componentes. Juntos, eles otimizam o fluxo de trabalho do desenvolvedor.
Ambiente de Desenvolvimento
Para seguir este guia, é necessário configurar a biblioteca ImGui com um backend OpenGL. Certifique-se de que seu projeto C++ inclua as dependências corretas para compilar e executar os exemplos a seguir.
Implementação do Painel Hierarchy
O painel Hierarchy renderiaz uma árvore interativa de objetos de jogo. Utilizamos componentes ImGui como TreeNodeEx para criar nós expansíveis e rastrear a seleção do usuário.
Passos principais:
- Percorrer recursivamente a árvore de objetos a partir do nó raiz.
- Desenhar cada nó com ícones de expansão/colapso e indicadores de seleção.
- Processar eventos de clique para atualizar o elemento selecionado.
Exemplo de código em C++ com ImGui:
// Arquivo: editor_hierarchy.cpp
void RenderHierarchy(HierarchyNode* node, const std::string& label, int baseFlags) {
int flags = baseFlags;
if (currentSelection == node) {
flags |= ImGuiTreeNodeFlags_Selected;
}
const auto& childNodes = node->GetChildren();
if (!childNodes.empty()) {
bool isOpen = ImGui::TreeNodeEx(label.c_str(), flags);
if (ImGui::IsItemClicked()) {
currentSelection = node;
}
if (isOpen) {
for (HierarchyNode* child : childNodes) {
GameObject* obj = static_cast<gameobject>(child);
RenderHierarchy(child, obj->GetName(), baseFlags);
}
ImGui::TreePop();
}
} else {
flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen;
ImGui::TreeNodeEx(label.c_str(), flags);
if (ImGui::IsItemClicked()) {
currentSelection = node;
}
}
}</gameobject>
Este código produz uma interface de árvore onde os objetos podem ser expandidos ou colapsados, com seleção visual ao clicar.
Implementação do Painel Inspector
O painel Inspector exibe e edita propriedades do objeto de jogo selecionado, incluindo atributos básicos e componentes como Transform.
Passos principais:
- Exibir propriedades do GameObject, como estado ativo e camada.
- Renderizar propriedades do componente Transform: posição, rotação e escala.
- Atualizar os valores em tempo real conforme o usuário insere dados.
Exemplo de código em C++ para o Inspector:
// Arquivo: editor_inspector.cpp
void DrawInspector() {
ImGui::Begin("Inspector");
GameObject* selectedObj = dynamic_cast<gameobject>(currentSelection);
if (selectedObj) {
// Propriedades do GameObject
bool isActive = selectedObj->IsActive();
if (ImGui::Checkbox("Ativo", &isActive)) {
selectedObj->SetActive(isActive);
}
int layer = selectedObj->GetLayer();
if (ImGui::InputInt("Camada", &layer)) {
selectedObj->SetLayer(layer);
}
// Propriedades do Transform
Transform* transform = selectedObj->GetComponent<Transform>();
if (transform) {
glm::vec3 pos = transform->GetPosition();
glm::vec3 rot = transform->GetRotation();
glm::vec3 scl = transform->GetScale();
if (ImGui::TreeNode("Transform")) {
if (ImGui::InputFloat3("Posição", &pos.x)) {
transform->SetPosition(pos);
}
if (ImGui::InputFloat3("Rotação", &rot.x)) {
transform->SetRotation(rot);
}
if (ImGui::InputFloat3("Escala", &scl.x)) {
transform->SetScale(scl);
}
ImGui::TreePop();
}
}
} else {
ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Nenhum GameObject válido selecionado.");
}
ImGui::End();
}</gameobject>
Este painel permite edição interativa de atributos, sincronizando alterações com o motor de jogo.
Considerações de Extensão
Após implementar os painéis básicos, é possível expandir funcionalidades adicionando suporte a mais componentes, validação de propriedades, edição em lote e sistemas de desfazer/refazer.