You are viewing documentation for v1.1. Switch to current version โ†’

๐Ÿง™โ€โ™‚๏ธ Library Wizard

Short Description

The Library Wizard is a dynamic asset browsing and creation interface that lets users explore categorized templates and generate new assets via the Gorgeous Setup Wizard. It pairs searchable, filterable library views with template-driven creation workflows.

Long Description

The Library Wizard organizes editor-facing templates and assets into named categories and exposes them in a tiled browser. Participants (plugin modules) register categories and templates; tiles can open a multi-page Setup Wizard driven by UGorgeousSystemTemplate_DA + UGorgeousSetupWizardPayload classes. The system supports advanced filtering, custom icons, and per-category actions to streamline common creation tasks.

Quick start (for plugin authors)

  1. Create a UGorgeousSystemTemplate_DA subclass describing the template (title, icon, asset class to create, and payload page classes).
  2. Provide one or more UGorgeousSetupWizardPayload subclasses to render wizard pages and validate input.
  3. Implement an IGorgeousLibraryParticipant in your module and return category descriptors via GetLibraryCategories().
  4. Ensure your module exposes a LibraryParticipant pointer (set on startup) so SGorgeousLibraryView discovers it.
  5. Test in-editor: open the Library, select a template tile, fill pages, and finish to create the target asset.

How the wizard flow works

  • User clicks a template tile (tile detected via Asset Registry query using AssetClassPath).
  • If bOpensSetupWizard is true the Library opens SGorgeousSetupWizard.
  • The wizard instantiates each configured ConfigurationPayloadClasses as page objects and renders them via IDetailsView.
  • On Finish: the wizard creates an instance of AssetClassToCreate (a UPrimaryDataAsset subclass), saves it, and calls ExecuteTemplateGeneration() on the generated asset with the payload objects.

Creating a template (example)

UCLASS()
class UGorgeousInventoryTemplate_DA : public UGorgeousSystemTemplate_DA
{
    GENERATED_BODY()

public: UGorgeousInventoryTemplate_DA() { TemplateTitle = NSLOCTEXT("GorgeousInventory", "Template_Title", "Inventory Setup"); TemplateDescription = NSLOCTEXT("GorgeousInventory", "Template_Desc", "Create a basic inventory configuration."); // TemplateIcon: assign a UTexture2D in the editor AssetClassToCreate = UGorgeousInventoryConfig_DA::StaticClass(); // example asset class ConfigurationPayloadClasses = { UGorgeousInventoryPayload::StaticClass() }; }

<span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">bool</span> <span class="hljs-title">ExecuteTemplateGeneration_Implementation</span><span class="hljs-params">(UObject* GeneratedAsset, <span class="hljs-type">const</span> TArray&lt;UObject*&gt;&amp; PayloadData)</span> <span class="hljs-type">const</span> <span class="hljs-keyword">override</span>
</span>{
    <span class="hljs-keyword">if</span> (UGorgeousInventoryConfig_DA* Config = <span class="hljs-built_in">Cast</span>&lt;UGorgeousInventoryConfig_DA&gt;(GeneratedAsset))
    {
        <span class="hljs-comment">// Populate Config from PayloadData (cast payloads as needed)</span>
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}

};

Wizard payload pages

Payload classes render as wizard pages and provide validation hooks.

Auto-mapping: The Library Wizard will attempt to copy property values from payload objects onto the generated asset when a payload UPROPERTY name and type match a property on the asset to create. This automatic mapping uses Unreal's reflection system (UPROPERTY/FProperty) to assign values so simple configuration fields commonly transfer without custom code. To customize or opt out of automatic copying, override PostCreate() in the payload or perform mapping manually inside ExecuteTemplateGeneration() on the generated asset.


UCLASS(Blueprintable, EditInlineNew)
class UGorgeousInventoryPayload : public UGorgeousSetupWizardPayload
{
    GENERATED_BODY()

public: UPROPERTY(EditAnywhere, Category = "Setup") int32 DefaultStackSize = 100;

<span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">bool</span> <span class="hljs-title">PreCreate_Implementation</span><span class="hljs-params">(FString&amp; OutFailureReason)</span> <span class="hljs-keyword">override</span>
</span>{
    <span class="hljs-keyword">if</span> (DefaultStackSize &lt;= <span class="hljs-number">0</span>) { OutFailureReason = <span class="hljs-built_in">TEXT</span>(<span class="hljs-string">&quot;Default stack size must be &gt; 0&quot;</span>); <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}

<span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">bool</span> <span class="hljs-title">PostCreate_Implementation</span><span class="hljs-params">(UObject* CreatedAsset, FString&amp; OutFailureReason)</span> <span class="hljs-keyword">override</span> </span>{ <span class="hljs-comment">// Finalize the generated asset after save</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; }

};

Implementing an IGorgeousLibraryParticipant

Participants expose categories, custom icons, and optional behaviors (context menu, double-click). Return a list of FGorgeousLibraryCategoryDescriptor via GetLibraryCategories().

class FMyLibraryParticipant : public IGorgeousLibraryParticipant
{
public:
    virtual FName GetParticipantName() const override { return TEXT("MyPlugin"); }
    virtual FText GetParticipantDisplayName() const override { return NSLOCTEXT("MyPlugin","DisplayName","My Plugin"); }

<span class="hljs-function"><span class="hljs-keyword">virtual</span> TArray&lt;FGorgeousLibraryCategoryDescriptor&gt; <span class="hljs-title">GetLibraryCategories</span><span class="hljs-params">()</span> <span class="hljs-type">const</span> <span class="hljs-keyword">override</span>
</span>{
    FGorgeousLibraryCategoryDescriptor Cat;
    Cat.CategoryId = <span class="hljs-built_in">TEXT</span>(<span class="hljs-string">&quot;MyTemplates&quot;</span>);
    Cat.DisplayName = <span class="hljs-built_in">NSLOCTEXT</span>(<span class="hljs-string">&quot;MyPlugin&quot;</span>,<span class="hljs-string">&quot;Templates&quot;</span>,<span class="hljs-string">&quot;Templates&quot;</span>);
    Cat.AssetClassPath = <span class="hljs-built_in">FTopLevelAssetPath</span>(<span class="hljs-built_in">TEXT</span>(<span class="hljs-string">&quot;/Script/MyPlugin&quot;</span>), <span class="hljs-built_in">TEXT</span>(<span class="hljs-string">&quot;MyTemplate_DA&quot;</span>));
    Cat.bOpensSetupWizard = <span class="hljs-literal">true</span>;
    Cat.ViewMode = EGorgeousLibraryViewMode::Grid;
    Cat.bHasSearchFilter = <span class="hljs-literal">true</span>;
    Cat.bEnableAdvancedFiltering = <span class="hljs-literal">true</span>;
    <span class="hljs-keyword">return</span> { Cat };
}

};

In your module's startup assign your participant instance so the library can discover it (mirror pattern used by IGorgeousThingsModuleInterface).

Filters & actions

  • Use GetFilters(CategoryId) to provide FGorgeousLibraryFilter tags that appear as toggles.
  • Populate CategoryActions with FGorgeousLibraryCategoryAction to show header buttons (e.g., Create, +).

Iconography & tiles

  • Templates may provide TemplateIcon (a UTexture2D) โ€” GetAssetIcon() will use it if present.
  • Provide meaningful TemplateTitle and TemplateDescription for discoverability.

Best practices

  • Mark templates as editor-only (IsEditorOnly() returns true) โ€” templates are not shipped into runtime builds.
  • Keep ExecuteTemplateGeneration() idempotent and robust: validate payload types and return false with a clear error if generation fails.
  • Keep wizard pages focused and validate user input in PreCreate() to avoid blocking finish flows.

Troubleshooting

  • Tile not appearing: verify AssetClassPath and that assets are saved where the Asset Registry can find them.
  • Wizard refuses to finish: check PreCreate() return values and OutFailureReason strings.
  • Created asset missing values: ensure ExecuteTemplateGeneration() copies payload values and marks the asset dirty if necessary (Modify()).

Plugins participating must override IGorgeousLibraryParticipant and set the reference in their module interface as described above.