Skip to content

4.6 Prefab System #124

Description

@LyeZinho

🔧 Prefab System

Milestone: M4 — Advanced Tools & Polish
Namespace: Caffeine::Editor
Arquivos: src/editor/PrefabSystem.hpp, src/editor/PrefabSystem.cpp
Status: 📅 Planeado
RF: RF6.6


VisĂŁo Geral

O Prefab System Ă© uma ferramenta fundamental para a escalabilidade e reutilização de conteĂșdo no Caffeine Studio. Um "Prefab" (abreviatura de Prefabricated) Ă© um modelo de entidade ou hierarquia de entidades que pode ser guardado como um asset (.prefab.caf) e instanciado mĂșltiplas vezes em diferentes cenas.

A principal força deste sistema reside na sua natureza dinĂąmica: qualquer alteração feita no ficheiro original do Prefab propaga-se automaticamente para todas as suas instĂąncias na cena. No entanto, o sistema tambĂ©m suporta "Overrides", permitindo que instĂąncias especĂ­ficas tenham valores de propriedades diferentes (ex: uma posição ou cor Ășnica) sem quebrar a ligação com o modelo base. O suporte para "Prefab Nesting" permite criar prefabs complexos a partir de prefabs mais simples (ex: um prefab de Carro que contĂ©m prefabs de Rodas).


Implementação

O sistema gere a relação entre o asset em disco e as entidades instanciadas através de um ID de ligação (PrefabID).

Estrutura do Sistema de Prefabs

namespace Caffeine::Editor {

struct PrefabOverride {
    UUID entityID;
    std::string componentName;
    std::string propertyName;
    std::variant<int, float, std::string, glm::vec3> value;
};

class PrefabInstanceComponent {
public:
    UUID prefabSourceID;
    std::vector<PrefabOverride> overrides;
    
    bool IsOverridden(const std::string& comp, const std::string& prop) const;
};

class PrefabManager {
public:
    // Criar um novo asset de prefab a partir de uma entidade existente
    static Ref<Prefab> CreateFromEntity(Entity entity, const std::string& path);
    
    // Instanciar um prefab na cena ativa
    static Entity Instantiate(Ref<Prefab> prefab, Scene* scene);
    
    // Aplicar alteraçÔes de uma instùncia de volta para o asset (Push changes)
    static void ApplyOverridesToPrefab(Entity instance);
    
    // Reverter uma instĂąncia para o estado original do asset
    static void RevertOverrides(Entity instance);

private:
    static void PropagateChanges(Ref<Prefab> prefab);
};

} // namespace Caffeine::Editor

Lógica de Propagação (Pseudo-C++)

void PrefabManager::PropagateChanges(Ref<Prefab> prefab) {
    auto activeScenes = Editor::GetActiveScenes();
    for (auto scene : activeScenes) {
        auto view = scene->m_registry.view<PrefabInstanceComponent>();
        for (auto entity : view) {
            auto& instance = view.get<PrefabInstanceComponent>(entity);
            if (instance.prefabSourceID == prefab->ID) {
                // Atualizar componentes, mantendo os overrides locais
                UpdateInstanceFromPrefab(entity, prefab, instance.overrides);
            }
        }
    }
}

Diagrama de Hierarquia e Overrides (ASCII)

┌─────────────────────────────────────────────────────────────┐
│ Scene Hierarchy                                             │
├──────────────────────────────────────────────────────────────
│ â–Œ Scene_Main                                                │
│   ▾ Camera                                                  │
│   ▾ Light_Directional                                       │
│   â–Œ [🟩] Prefab: Hero_Instance_01  (Linked)                 │
│     └─ [đŸ”č] Transform  [pos: 10, 0] <-- OVERRIDDEN          │
│     └─ [đŸ”č] Sprite     [id: hero_idle]                      │
│     └─ [đŸ”č] Script     [path: player.lua]                   │
│   â–Œ [🟩] Prefab: Enemy_Instance_A                           │
│     └─ [đŸ”č] Transform  [pos: 50, 20]                        │
│     └─ [đŸ”č] Sprite     [id: enemy_bat]                      │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ Inspector (Hero_Instance_01)                                │
├──────────────────────────────────────────────────────────────
│ [Prefab Controls]   [Revert All] [Apply to Prefab]          │
│                                                             │
│ [x] Transform                                               │
│     - Position: [ 10.0 ] [  0.0 ]  <-- (Texto a Negrito)    │
│ [ ] Sprite                                                  │
│     - Texture: [ hero_idle    ]  [v]                        │
└─────────────────────────────────────────────────────────────┘

DecisÔes de Design

DecisĂŁo Justificativa
Gravação em Formato Binårio Otimiza o carregamento de grandes quantidades de instùncias durante o runtime.
Sistema de Overrides Granular Permite personalização extrema sem perder a facilidade de manutenção global.
Prefab Nesting Crucial para projetos complexos onde objetos sĂŁo compostos por outros sub-objetos modulares.
Ícones Distintos na Hierarquia Ajuda o utilizador a identificar rapidamente o que Ă© um objeto Ășnico e o que Ă© uma instĂąncia de um template.

Critério de Aceitação

  • Criação de Prefabs a partir de qualquer entidade via drag-and-drop para o Asset Browser.
  • Instanciação correta de Prefabs no Scene Viewport mantendo a hierarquia original.
  • Deteção automĂĄtica de alteraçÔes em propriedades e marcação como "Override".
  • BotĂŁo "Apply" que guarda as alteraçÔes da instĂąncia no asset base.
  • BotĂŁo "Revert" que descarta overrides locais e restaura os valores do asset.

DependĂȘncias

  • Upstream: docs/ecs/scene.md (necessĂĄrio para a gestĂŁo de entidades e componentes)
  • Downstream: docs/editor/scene-editor.md (integração visual na hierarquia)

🔗 Tópicos Relacionados

Tópico Descrição
ECS Core Como as entidades e componentes sĂŁo estruturados internamente.
Serialization O processo de converter entidades em ficheiros YAML/BinĂĄrio.
Asset Browser Onde os ficheiros .prefab.caf sĂŁo visualizados e geridos.

ReferĂȘncias

  • AnĂĄlise do sistema de Prefabs do Unity e Blueprint Classes do Unreal Engine.
  • PadrĂŁo de design "Prototype" aplicado a sistemas de entidades.
  • TĂ©cnicas de diff e merge de dados para reconciliação de overrides.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions