首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >提高基于组件的游戏引擎的效率

提高基于组件的游戏引擎的效率
EN

Stack Overflow用户
提问于 2018-09-29 06:10:50
回答 1查看 64关注 0票数 0

我正在尝试构建一个基于组件的游戏引擎,但我的效率肯定是不足的。这个问题在我的冲突检测中最为明显,因为我会将每个GameObject与其他GameObject进行比较,以查看它们是否发生冲突。下面是碰撞检测函数:

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);
        }
    }
}

我试图通过忽略与当前GameObject不接近的GameObjects来提高效率,使用碰撞半径,但这似乎没有任何作用,真正导致问题的代码行是

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中查找对象是一个恒定的时间操作,所以我不确定如何提高速度。有没有更有效的方法来处理我的组件?任何帮助都将不胜感激,谢谢!

EN

回答 1

Stack Overflow用户

发布于 2018-09-29 08:02:40

您查询内循环中的组件以获取moveObjects.size()时间,这意味着大量的冗余工作。

您应该将预处理循环放在收集组件的主循环之前:

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;
    }

    // add pComponent2 and rComponent2 into an array here
}

然后,在内部循环中,使用收集的数据,而不是从管理器查询数据。

请注意,如果您有很多对象,您可能希望将它们放入一些空间分区数据结构(八叉树/Kd-树/BSP-tree)中,以避免O(n^2)运行时间。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52563219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档