Queries Filters
ΠΡΠ½ΠΎΠ²Ρ Π·Π°ΠΏΡΠΎΡΠΎΠ²
ΠΠ°ΠΏΡΠΎΡΡ Π² Wudgine ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ ΡΠΈΡΡΠ΅ΠΌΠ°ΠΌ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡ ΡΡΡΠ½ΠΎΡΡΠΈ Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΌΠΈ Π½Π°Π±ΠΎΡΠ°ΠΌΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ². ΠΡΠΎ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ Π΄Π»Ρ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π΄Π°Π½Π½ΡΡ Π² ECS.
Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΠΎΠ²
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡΠΎΡΡΠΎΠ³ΠΎ Π·Π°ΠΏΡΠΎΡΠ°
EntityQuery query = world.createQuery()
.with<TransformComponent>()
.with<MeshRendererComponent>()
.build();
// ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΠ°
query.forEach([](Entity entity, TransformComponent& transform, MeshRendererComponent& renderer) {
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΡΠ½ΠΎΡΡΠΈ Ρ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌΠΈ Transform ΠΈ MeshRenderer
});
Π’ΠΈΠΏΡ Π·Π°ΠΏΡΠΎΡΠΎΠ²
- ΠΠΊΠ»ΡΡΠ°ΡΡΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΡ: Π‘ΡΡΠ½ΠΎΡΡΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΠΌΠ΅ΡΡ Π²ΡΠ΅ ΡΠΊΠ°Π·Π°Π½Π½ΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ
- ΠΡΠΊΠ»ΡΡΠ°ΡΡΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΡ: Π‘ΡΡΠ½ΠΎΡΡΠΈ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΠΌΠ΅ΡΡ ΡΠΊΠ°Π·Π°Π½Π½ΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ
- ΠΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ: ΠΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΠΌΠΎΠ³ΡΡ ΠΏΡΠΈΡΡΡΡΡΠ²ΠΎΠ²Π°ΡΡ ΠΈΠ»ΠΈ ΠΎΡΡΡΡΡΡΠ²ΠΎΠ²Π°ΡΡ
- ΠΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ: Π‘ΠΎΡΠ΅ΡΠ°Π½ΠΈΠ΅ Π²ΠΊΠ»ΡΡΠ°ΡΡΠΈΡ , ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠΈΡ ΠΈ ΠΎΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΡ ΡΡΠ»ΠΎΠ²ΠΈΠΉ
// ΠΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ Π·Π°ΠΏΡΠΎΡ
EntityQuery query = world.createQuery()
.with<TransformComponent>() // ΠΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ
.with<RigidbodyComponent>() // ΠΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ
.without<StaticComponent>() // ΠΡΠΊΠ»ΡΡΠ°ΡΡΠΈΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ
.optional<ColliderComponent>() // ΠΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ
.build();
// ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΠ° Ρ ΠΎΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠΌ
query.forEach([](Entity entity,
TransformComponent& transform,
RigidbodyComponent& rigidbody,
OptionalComponent<ColliderComponent> collider) {
// ΠΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π°Π»ΠΈΡΠΈΡ ΠΎΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°
if (collider) {
// ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ° ΠΊΠΎΠ»Π»Π°ΠΉΠ΄Π΅ΡΠ°
auto& colliderComponent = collider.get();
// ...
} else {
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠ»ΡΡΠ°Ρ ΠΎΡΡΡΡΡΡΠ²ΠΈΡ ΠΊΠΎΠ»Π»Π°ΠΉΠ΄Π΅ΡΠ°
// ...
}
});
Π€ΠΈΠ»ΡΡΡΡ
Π€ΠΈΠ»ΡΡΡΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ² ΠΈΠ»ΠΈ Π΄ΡΡΠ³ΠΈΡ ΠΊΡΠΈΡΠ΅ΡΠΈΠ΅Π².
Π€ΠΈΠ»ΡΡΡΡ ΠΏΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ²
// ΠΠ°ΠΏΡΠΎΡ Ρ ΡΠΈΠ»ΡΡΡΠΎΠΌ ΠΏΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°
EntityQuery query = world.createQuery()
.with<TransformComponent>()
.with<HealthComponent>()
.where<HealthComponent>([](const HealthComponent& health) {
// Π’ΠΎΠ»ΡΠΊΠΎ ΡΡΡΠ½ΠΎΡΡΠΈ Ρ Π·Π΄ΠΎΡΠΎΠ²ΡΠ΅ΠΌ Π½ΠΈΠΆΠ΅ 50%
return health.currentHealth < health.maxHealth * 0.5f;
})
.build();
// ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΠ° Ρ ΡΠΈΠ»ΡΡΡΠΎΠΌ
query.forEach([](Entity entity, TransformComponent& transform, HealthComponent& health) {
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ Ρ Π½ΠΈΠ·ΠΊΠΈΠΌ Π·Π΄ΠΎΡΠΎΠ²ΡΠ΅ΠΌ
});
ΠΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ ΡΠΈΠ»ΡΡΡΡ
// ΠΠ°ΠΏΡΠΎΡ Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ ΡΠΈΠ»ΡΡΡΠ°ΠΌΠΈ
EntityQuery query = world.createQuery()
.with<TransformComponent>()
.with<AIComponent>()
.with<HealthComponent>()
.where<AIComponent, TransformComponent>([](const AIComponent& ai, const TransformComponent& transform) {
// Π’ΠΎΠ»ΡΠΊΠΎ Π°ΠΊΡΠΈΠ²Π½ΡΠ΅ AI Π² ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ Π·ΠΎΠ½Π΅
return ai.isActive && transform.position.y < 10.0f;
})
.where<HealthComponent>([](const HealthComponent& health) {
// Π’ΠΎΠ»ΡΠΊΠΎ Ρ Π·Π΄ΠΎΡΠΎΠ²ΡΠ΅ΠΌ Π²ΡΡΠ΅ Π½ΡΠ»Ρ
return health.currentHealth > 0.0f;
})
.build();
Π€ΠΈΠ»ΡΡΡΡ ΠΏΠΎ ΡΠ΅Π³Π°ΠΌ ΠΈ ΡΠ»ΠΎΡΠΌ
// ΠΠ°ΠΏΡΠΎΡ Ρ ΡΠΈΠ»ΡΡΡΠΎΠΌ ΠΏΠΎ ΡΠ΅Π³Π°ΠΌ
EntityQuery query = world.createQuery()
.with<TransformComponent>()
.withTag("Enemy")
.withoutTag("Boss")
.build();
// ΠΠ°ΠΏΡΠΎΡ Ρ ΡΠΈΠ»ΡΡΡΠΎΠΌ ΠΏΠΎ ΡΠ»ΠΎΡΠΌ
EntityQuery query = world.createQuery()
.with<TransformComponent>()
.with<ColliderComponent>()
.inLayer(PhysicsLayer::Enemies)
.notInLayer(PhysicsLayer::Triggers)
.build();
ΠΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΠΎΠ²
ΠΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΠΎΠ²
class EnemySystem : public ISystem {
private:
World* m_world;
EntityQuery m_activeEnemiesQuery;
EntityQuery m_inactiveEnemiesQuery;
public:
EnemySystem(World* world) : m_world(world) {
// ΠΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΠΎΠ² ΠΏΡΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ
m_activeEnemiesQuery = m_world->createQuery()
.with<EnemyComponent>()
.with<TransformComponent>()
.where<EnemyComponent>([](const EnemyComponent& enemy) {
return enemy.isActive;
})
.build();
m_inactiveEnemiesQuery = m_world->createQuery()
.with<EnemyComponent>()
.with<TransformComponent>()
.where<EnemyComponent>([](const EnemyComponent& enemy) {
return !enemy.isActive;
})
.build();
}
void update(float deltaTime) override {
// ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΡΡΠΈΡΠΎΠ²Π°Π½Π½ΡΡ
Π·Π°ΠΏΡΠΎΡΠΎΠ²
updateActiveEnemies(deltaTime);
activateInactiveEnemies();
}
private:
void updateActiveEnemies(float deltaTime) {
m_activeEnemiesQuery.forEach([deltaTime](Entity entity,
EnemyComponent& enemy,
TransformComponent& transform) {
// ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π°ΠΊΡΠΈΠ²Π½ΡΡ
Π²ΡΠ°Π³ΠΎΠ²
// ...
});
}
void activateInactiveEnemies() {
// ΠΠΊΡΠΈΠ²Π°ΡΠΈΡ Π½Π΅Π°ΠΊΡΠΈΠ²Π½ΡΡ
Π²ΡΠ°Π³ΠΎΠ² ΠΏΡΠΈ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ
// ...
}
};
ΠΡΡ Π΅ΡΠΈΠΏΡ ΠΈ ΡΠ°Π½ΠΊΠΈ
Wudgine ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π°ΡΡ Π΅ΡΠΈΠΏΡ ΠΈ ΡΠ°Π½ΠΊΠΈ Π΄Π»Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΠΈ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌ:
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π°ΡΡ
Π΅ΡΠΈΠΏΠ°
EntityArchetype characterArchetype = world.createArchetype()
.with<TransformComponent>()
.with<CharacterControllerComponent>()
.with<AnimatorComponent>()
.with<HealthComponent>()
.build();
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ Π°ΡΡ
Π΅ΡΠΈΠΏΠ°
Entity player = world.createEntity(characterArchetype);
player.setName("Player");
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π° ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π°ΡΡ
Π΅ΡΠΈΠΏΠ°
std::vector<Entity> enemies = world.createEntities(characterArchetype, 100);
ΠΡΠ΅ΡΠ°ΡΠΈΡ ΠΏΠΎ ΡΠ°Π½ΠΊΠ°ΠΌ
// ΠΠ°ΠΏΡΠΎΡ Ρ ΠΈΡΠ΅ΡΠ°ΡΠΈΠ΅ΠΉ ΠΏΠΎ ΡΠ°Π½ΠΊΠ°ΠΌ Π΄Π»Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ ΠΊΡΡΠ°
EntityQuery query = world.createQuery()
.with<TransformComponent>()
.with<VelocityComponent>()
.build();
// ΠΡΠ΅ΡΠ°ΡΠΈΡ ΠΏΠΎ ΡΠ°Π½ΠΊΠ°ΠΌ
query.forEachChunk([deltaTime](EntityChunk chunk,
ComponentArray<TransformComponent> transforms,
ComponentArray<VelocityComponent> velocities) {
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π²ΡΠ΅Ρ
ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ Π² ΡΠ°Π½ΠΊΠ΅ Π·Π° ΠΎΠ΄ΠΈΠ½ ΠΏΡΠΎΡ
ΠΎΠ΄
for (size_t i = 0; i < chunk.size(); ++i) {
transforms[i].position += velocities[i].value * deltaTime;
}
});
ΠΡΠΎΠ΄Π²ΠΈΠ½ΡΡΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ
ΠΠ°ΠΏΡΠΎΡΡ Ρ ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΎΠΉ
// ΠΠ°ΠΏΡΠΎΡ Ρ ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΎΠΉ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ²
EntityQuery query = world.createQuery()
.with<TransformComponent>()
.with<HealthComponent>()
.build();
// ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΎΡΡΠΎΡΡΠΈΡΠΎΠ²Π°Π½Π½ΡΡ
ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ²
auto entities = query.getEntities();
std::sort(entities.begin(), entities.end(), [&world](Entity a, Entity b) {
// Π‘ΠΎΡΡΠΈΡΠΎΠ²ΠΊΠ° ΠΏΠΎ ΡΠ°ΡΡΡΠΎΡΠ½ΠΈΡ Π΄ΠΎ ΠΈΠ³ΡΠΎΠΊΠ°
const auto& transformA = a.getComponent<TransformComponent>();
const auto& transformB = b.getComponent<TransformComponent>();
Entity player = world.findEntityByName("Player");
Vector3 playerPos = player.getComponent<TransformComponent>().position;
float distA = Vector3::distance(transformA.position, playerPos);
float distB = Vector3::distance(transformB.position, playerPos);
return distA < distB;
});
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΎΡΡΠΎΡΡΠΈΡΠΎΠ²Π°Π½Π½ΡΡ
ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ
for (auto entity : entities) {
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ Π² ΠΏΠΎΡΡΠ΄ΠΊΠ΅ Π±Π»ΠΈΠ·ΠΎΡΡΠΈ ΠΊ ΠΈΠ³ΡΠΎΠΊΡ
// ...
}
ΠΠ°ΠΏΡΠΎΡΡ Ρ ΠΏΠ°Π³ΠΈΠ½Π°ΡΠΈΠ΅ΠΉ
// ΠΠ°ΠΏΡΠΎΡ Ρ ΠΏΠ°Π³ΠΈΠ½Π°ΡΠΈΠ΅ΠΉ Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π±ΠΎΠ»ΡΡΠΈΡ
Π½Π°Π±ΠΎΡΠΎΠ² Π΄Π°Π½Π½ΡΡ
EntityQuery query = world.createQuery()
.with<AIComponent>()
.with<TransformComponent>()
.build();
// ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΏΠ°Π³ΠΈΠ½Π°ΡΠΈΠΈ
size_t pageSize = 50;
size_t totalEntities = query.count();
size_t pageCount = (totalEntities + pageSize - 1) / pageSize;
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ ΠΏΠΎΡΡΡΠ°Π½ΠΈΡΠ½ΠΎ
for (size_t page = 0; page < pageCount; ++page) {
size_t offset = page * pageSize;
size_t limit = std::min(pageSize, totalEntities - offset);
query.forEachSlice(offset, limit, [](Entity entity,
AIComponent& ai,
TransformComponent& transform) {
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ Π½Π° ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΡΡΡΠ°Π½ΠΈΡΠ΅
// ...
});
}
ΠΠ°ΠΏΡΠΎΡΡ Ρ Π³ΡΡΠΏΠΏΠΈΡΠΎΠ²ΠΊΠΎΠΉ
// ΠΠ°ΠΏΡΠΎΡ Ρ Π³ΡΡΠΏΠΏΠΈΡΠΎΠ²ΠΊΠΎΠΉ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ²
EntityQuery query = world.createQuery()
.with<TransformComponent>()
.with<TeamComponent>()
.build();
// ΠΡΡΠΏΠΏΠΈΡΠΎΠ²ΠΊΠ° ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ ΠΏΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌ
std::unordered_map<int, std::vector<Entity>> teamGroups;
query.forEach([&teamGroups](Entity entity,
TransformComponent& transform,
TeamComponent& team) {
// ΠΡΡΠΏΠΏΠΈΡΠΎΠ²ΠΊΠ° ΠΏΠΎ ID ΠΊΠΎΠΌΠ°Π½Π΄Ρ
teamGroups[team.teamId].push_back(entity);
});
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠ³ΡΡΠΏΠΏΠΈΡΠΎΠ²Π°Π½Π½ΡΡ
ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ
for (auto& [teamId, entities] : teamGroups) {
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π²ΡΠ΅Ρ
ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ Π² ΠΊΠΎΠΌΠ°Π½Π΄Π΅
// ...
}
ΠΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΡ
ΠΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΠΎΠ² Π²ΠΎ Π²ΡΠ΅ΠΌΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ Π·Π°ΠΏΡΠΎΡΠ°
DynamicEntityQuery dynamicQuery = world.createDynamicQuery();
// ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π·Π°ΠΏΡΠΎΡΠ° Π²ΠΎ Π²ΡΠ΅ΠΌΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ
void configureQuery(bool includeEnemies, bool includeBosses, float minHealth) {
// Π‘Π±ΡΠΎΡ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΡ
ΡΡΠ»ΠΎΠ²ΠΈΠΉ
dynamicQuery.reset();
// ΠΠ°Π·ΠΎΠ²ΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ
dynamicQuery.with<TransformComponent>();
dynamicQuery.with<HealthComponent>();
// ΠΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΡΠ»ΠΎΠ²ΠΈΡ
if (includeEnemies) {
dynamicQuery.withTag("Enemy");
}
if (!includeBosses) {
dynamicQuery.withoutTag("Boss");
}
// ΠΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΠΈΠ»ΡΡΡ
dynamicQuery.where<HealthComponent>([minHealth](const HealthComponent& health) {
return health.currentHealth >= minHealth;
});
// ΠΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
dynamicQuery.apply();
}
// ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ Π·Π°ΠΏΡΠΎΡΠ°
void processEntities() {
dynamicQuery.forEach([](Entity entity,
TransformComponent& transform,
HealthComponent& health) {
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ
// ...
});
}
ΠΠ°ΠΏΡΠΎΡΡ Ρ ΠΎΠ±ΡΠ°ΡΠ½ΡΠΌΠΈ Π²ΡΠ·ΠΎΠ²Π°ΠΌΠΈ ΠΏΡΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡΡ
// ΠΠ°ΠΏΡΠΎΡ Ρ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
EntityQuery query = world.createQuery()
.with<PlayerComponent>()
.with<HealthComponent>()
.trackChanges()
.build();
// Π Π΅Π³ΠΈΡΡΡΠ°ΡΠΈΡ ΠΎΠ±ΡΠ°ΡΠ½ΡΡ
Π²ΡΠ·ΠΎΠ²ΠΎΠ² Π΄Π»Ρ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
query.onEntityAdded([](Entity entity) {
Debug::log("Entity added to query: {}", entity.getName());
});
query.onEntityRemoved([](Entity entity) {
Debug::log("Entity removed from query: {}", entity.getName());
});
query.onComponentChanged<HealthComponent>([](Entity entity,
const HealthComponent& oldValue,
const HealthComponent& newValue) {
float healthDiff = newValue.currentHealth - oldValue.currentHealth;
if (healthDiff < 0) {
Debug::log("Entity {} took {} damage", entity.getName(), -healthDiff);
} else if (healthDiff > 0) {
Debug::log("Entity {} healed for {}", entity.getName(), healthDiff);
}
});
Π‘Π»Π΅Π΄ΡΡΡΠΈΠ΅ ΡΠ°Π³ΠΈ
Π’Π΅ΠΏΠ΅ΡΡ, ΠΊΠΎΠ³Π΄Π° Π²Ρ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΠ»ΠΈΡΡ Ρ Π·Π°ΠΏΡΠΎΡΠ°ΠΌΠΈ ΠΈ ΡΠΈΠ»ΡΡΡΠ°ΠΌΠΈ Π² Wudgine, ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌ: