在我正在开发的游戏引擎中,我有一个将实体作为其他实体的子实体的系统。它的工作方式:每个实体都有一个指向其父实体的指针,以及一个指向其子实体的指针向量。在我的编辑器中,我想要有一个特性,你可以在树上拖动实体来改变它们的父关系。我已经实现了拖放,以及一个在编辑器中绘制实体树的系统。
问:我该如何做真正的育儿?下面是拖放的样子:
if (ImGuiPayload const* payload = ImGui::AcceptDragDropPayload("entity_reparent_id")) {
int dragID = *static_cast<int*>(payload->Data);
// do the reparenting
}
ImGui::EndDragDropTarget();childID是被拖动的实体的ID。(我有一个函数可以根据实体ID返回指向该实体的指针)
因此,我需要从前一个父代的向量中删除实体,并将其添加到新的父代的向量中。我还需要确保实体不会被重定为子级,或者是它的任何子级的子级。如何做到这一点?
发布于 2020-07-11 13:38:23
首先为您的实体类编写一个IsDescendantOf()方法(如果您还没有这样的方法):
bool Entity :: IsDescendantOf(const Entity * possibleAncestor) const
{
const Entity * p = m_parent_ptr;
while(p)
{
if (p == possibleAncestor) return true;
p = p->m_parent_ptr;
}
return false;
}完成后,您现在可以调用proposedDestinationParentEntity->IsDescendantOf(draggedEntity)来确保您的父子关系操作不会最终在树中创建一个循环。如果返回true,停下来告诉用户他不能做他想做的事情。
假设调用返回false,那么实际的父子关系只是将draggedEntity从其以前的父节点的子节点列表中删除,将其添加到proposedDestinationParentEntity的子节点列表中,并将draggedEntity的m_parent_ptr更改为指向proposedDestinationParentEntity。
https://stackoverflow.com/questions/62845508
复制相似问题