【发布时间】:2018-09-28 22:10:50
【问题描述】:
我正在尝试构建一个基于组件的游戏引擎,我的效率肯定是欠缺的。这个问题在我的碰撞检测中最为明显,因为我将每个游戏对象与其他游戏对象进行比较以查看它们是否发生碰撞。这里是碰撞检测功能:
void PhysicsSystem::update(float dt) {
std::vector<GameEngine::GameObject> moveObjects = manager->getAllObjectsWithComponent("move");
std::vector<GameEngine::GameObject> physicsObjects = manager->getAllObjectsWithComponent("physics");
for (int i = 0; i < moveObjects.size(); i++) {
MoveComponent* mComponent = static_cast<MoveComponent*>(manager->getComponentByType("move", moveObjects[i]));
PhysicsComponent* pComponent = static_cast<PhysicsComponent*>(manager->getComponentByType("physics", moveObjects[i]));
RenderComponent* rComponent = static_cast<RenderComponent*>(manager->getComponentByType("render", moveObjects[i]));
if (pComponent == nullptr || mComponent == nullptr || rComponent == nullptr) {
continue;
}
if (!pComponent->isSolid()) {
continue;
}
glm::vec4 coords1 = rComponent->getRenderCoords();
for (int j = 0; j < physicsObjects.size(); j++) {
PhysicsComponent* pComponent2 = static_cast<PhysicsComponent*>(manager->getComponentByType("physics", physicsObjects[j]));
RenderComponent* rComponent2 = static_cast<RenderComponent*>(manager->getComponentByType("render", physicsObjects[j]));
if (pComponent2 == nullptr || rComponent2 == nullptr) {
continue;
}
if (!pComponent2->isSolid()) {
continue;
}
glm::vec4 coords2 = rComponent2->getRenderCoords();
int dist = sqrt(pow((coords1.x - coords2.x), 2) + pow((coords1.y - coords2.y), 2));
if (dist > pComponent->getCollisionRadius()) {
continue;
}
if (GameEngine::Physics::checkCollision(coords1, coords2)) {
pComponent->addCollision(coords2);
}
}
}
我试图通过使用碰撞半径忽略不接近当前游戏对象的游戏对象来提高效率,但这似乎没有任何作用,真正导致问题的代码行是
PhysicsComponent* pComponent2 = static_cast<PhysicsComponent*>(manager->getComponentByType("physics", physicsObjects[j]));
RenderComponent* rComponent2 = static_cast<RenderComponent*>(manager->getComponentByType("render", physicsObjects[j]));
这些调用我的 GameObjectManager 类中的一个函数。这是该函数的代码:
Component* GameObjectManager::getComponentByType(std::string type, GameObject object) {
std::unordered_map<std::string, std::unordered_map<GLuint, Component*>>::iterator it = componentsByType.find(type);
if (it == componentsByType.end()) {
return nullptr;
}
std::unordered_map<GLuint, Component*>::iterator it2 = it->second.find(object.getGameObjectID());
if (it2 == it->second.end()) {
return nullptr;
}
return it2->second;
}
如果我去掉这两条线,游戏速度会大大加快。有什么我做错了吗?我认为在 unordered_map 中查找对象是一个恒定时间操作,所以我不确定如何提高速度。有没有更有效的方式来处理我的组件?任何帮助将不胜感激,谢谢!
【问题讨论】:
-
您使用的是优化/发布版本吗?
-
通常你不会遍历对象而是遍历组件。在您的情况下,可能是物理组件。这将为您节省一次搜索。我已经看到 ECS 是用组件向量实现的,而不是哈希图,但这需要重写大部分代码库。
标签: c++ performance unordered-map