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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions