提高基于组件的游戏引擎的效率
Increase efficiency of component-based game engine
我正在尝试构建一个基于组件的游戏引擎,但我的效率肯定不足。这个问题在我的碰撞检测中最为明显,因为我将每个游戏对象与其他游戏对象进行比较,以查看它们是否发生冲突。以下是碰撞检测功能:
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中查找物体是一个恒定的时间操作,所以我不确定如何提高速度。有没有更有效的方法来处理我的组件?任何帮助将不胜感激,谢谢!
这里有很多地方我看到了小的改进,尽管其中一些可能会导致相对较大的改进。 您正在制作大量不需要制作的潜在大型数据的副本。
moveObjects
和physicsObjects
是向量,是原始数据的副本。 这些是否需要是副本,或者它们可以const &
存储在游戏管理器中的矢量?- 您有几次检查
pComponent
、mComponent
和rComponent
。 如果任何检查失败,请继续执行下一个对象。 获取这些值之一,检查它是否有nullptr
,然后获取下一个值。 先pComponent
,先检查它是否坚固,然后再进行其他两个。 - 对
pComponent2
和rComponent2
的j
循环执行相同的操作。 - 检查距离时,不要计算平方根。 改为比较距离的平方。
- 将
object
参数传递给getComponentByType
byconst &
,这样您就不会复制它。 您只能访问其中的一个字段。 - 使用基于范围的 for 循环。 如果无法做到这一点,请考虑将向量的大小存储在变量中,而不是在每次循环迭代中调用
size
。 编译器可能会优化冗余调用,但确定的唯一方法是检查生成的优化代码。
您查询内部循环中的组件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
}
然后,在内部循环中,使用收集的数据,而不是从管理器查询它。
请注意,如果你有很多对象,你可能希望将它们放入一些空间分区数据结构(octree/Kd-tree/BSP-tree(中,以避免O(n^2)
运行时间。
相关文章:
- 当使用带有VS2019或VSCode的虚幻引擎4.24.2时,我如何修复这些错误的Intellisense错误
- Unity在虚幻引擎4中的"Vector3.Slerp"等效C++?
- 如何创建从Maya(或类似程序)到虚幻引擎的自定义数据导出插件
- 为什么当我解模块化时,这个C++代代码"效率较低"?
- 在虚幻引擎中删除NXOpen对象时崩溃
- 引擎节点:未定义的符号:_ZTV6Config
- Agora.io 虚幻引擎插件构建错误
- 代码的效率. 转到和函数调用
- <random>在实践中应该实际使用哪个随机数引擎? std::mt19937?
- 对于循环C++可能效率低下
- 无法在 Arch Linux 中启动虚幻引擎 4
- 内存效率表示最短路径的方法?
- 如何提高该函数的运行效率?
- 效率:标准::数组与标准::矢量
- 如何提高BST的搜索操作效率?
- 在虚幻引擎中触发C++ dll的事件
- 在 C/C++ 中加载 OpenSSL 自定义引擎
- 组件上的虚幻引擎可蓝图UFUNCTION会导致构建错误
- 使用Visual Studio在虚幻引擎中创建一个新的类c ++给了我太多的错误
- 提高基于组件的游戏引擎的效率