Documentation

Queries Filters

Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ запросы ΠΈ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ Π² систСмС ECS Wudgine, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ эффСктивно Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ сущности с ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌΠΈ Π½Π°Π±ΠΎΡ€Π°ΠΌΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ².

ΠžΡΠ½ΠΎΠ²Ρ‹ запросов

Запросы Π² 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, Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ:

Π’Π΅Π±-интСрфСйсы

Π˜Π·ΡƒΡ‡ΠΈΡ‚Π΅, ΠΊΠ°ΠΊ ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΅Π±-Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ Π² ваши ΠΈΠ³Ρ€Ρ‹.

ΠŸΠ»Π°Π³ΠΈΠ½Ρ‹

Π£Π·Π½Π°ΠΉΡ‚Π΅, ΠΊΠ°ΠΊ Ρ€Π°ΡΡˆΠΈΡ€ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π΄Π²ΠΈΠΆΠΊΠ° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ².

Wudgine β€’ Β© 2025