Hierarchy window : Technical Document
Context
I had to make a hierarchy window tool for the AerRacers project of the 3rd years. This tool is for the Neko Engine, which is a custom engine in c++, and I am using DearImGui to make it.
Needs for the tool
The hierarchy needs to be able to view entities, their children, select an entity, drag and drop them as well as add or delete an entity.
Interface overview
The window is called Hierarchy and you can see each entity and their children.
Description
View and select entities
To see an entity’s children, you need to click on the arrow. When you do so, the entity you selected is highlighted.
Add/Delete entity
To add an entity, you need to make a right click near an entity in the Hierarchy window, then you select the “Add Entity” option and you have now a new entity.
You can add as many entities as you want.
To delete an entity, you need to select it, right click, then click on the “Delete Entity” option.
Drag and Drop entity
To drag and drop an entity, you need to left click on the entity of your choice and hold the mouse button down. Then you drag it over the entity of your choice and release the left mouse button. Entity 7 is now a child of Entity 6.
Implementation
Show window
First, in order to have a window for our Hierarchy we need to show it in the editor with the DrawImGui function.
Show entities
To show our entities, we use a string for the Entity text and add a number to differenciate them.
Display children
Now, we need to display their children. For this, you make a loop that checks all entities. After that, if the entity is a child of the entity you’re checking, you display it in the Hierarchy.
However, when you do that there’s a new problem. In the Hierarchy, there will be arrows on all entities, even those that don’t have a child.
What we want is that there is no arrow if there is no child.
Add and Delete entities menu
To make a menu appear when you right click, I used the ImGui::BeginPopupContextItem(). Then, in the if condition, you use ImGui::MenuItem(“”) and put the name of your option in the quotation marks. For each option (here add and delete entity) you create/destroy your entity depending on the one you click in the menu.
Drag and drop entity
For this, you need to register your entity in payload using ImGui::SetDragDropPayLoad().
And you write a condition when you drop your entities on a parent.
Encountered problems
Show entities individually
My first problem was showing each entity individually. What I had in the beginning was the Hierarchy showing the number of entities :
Where entities were created in a Hierarchy test :
With this code :
The problem was solved by making a loop that gets all entities and shows them all individually with a number.
Show children and loop
The other problem was being able to have a child of a child of a child etc. At first the code was only able to check wether he was the child of the parent or not and show it in the Hierarchy. I made a DisplayChildren() function which makes it able to keep on having children with no limitations. The DisplayChildren() function is called in the DrawImGui() function.
Select an entity
I had a few problems with making an entity selectable. No matter what I did, it wouldn’t show the entity being selected, or it would put a color on all entities. What I needed to do to make it work was to make sure the selected entity had a flag on it (because when I first tried making the entity selectable, I wasn’t making sure that the entity was selected first before trying to show in the Hierarchy that it was).
Conclusion
To conclude, this project was interesting because it was the first time I was working for another group’s project and joining during development. It also made me realise the pressure you have when you work for someone else, people are counting on you and your work. Overall, it was a great experience.
Links
Engine : Neko Engine https://github.com/EliasFarhan/NekoEngine.
Hierarchy branch in AerRacers Project : https://github.com/SAE-Institute-Geneva/AerRacers/tree/tool/engine/inspector_hierarchy_hot_fix.