ParagonVisualElement

Abstract base class for reusable Paragon visual elements. Extends Unity's VisualElement with a managed lifecycle (create → initialize → destroy), automatic UXML template loading via [UxmlTemplate], element querying helpers, and guard-based single-creation semantics. The workhorse base for all custom UI elements in the Paragon editor framework.

Definition

Namespace: Paragon.Editor Assembly: Paragon.Editor.dll

public abstract class ParagonVisualElement : VisualElement

Inheritance: VisualElement → ParagonVisualElement

Remarks

The creation lifecycle is guarded by a created flag — CreateGUI() will only execute once, even if called multiple times or triggered by both the constructor (createImmediately) and the panel attach event. The lifecycle is:

  1. Construction — Registers AttachToPanelEvent and DetachFromPanelEvent callbacks. Optionally calls CreateGUI() immediately.

  2. CreateGUI() — Loads the UXML template via GetTemplateAsset(), clones it, copies style sheets, then calls OnCreateGUI(). Schedules Initialize() via delayCall.

  3. OnInitialize() — Runs one frame after OnCreateGUI(). Sets Initialized to true.

  4. OnDestroy() — Called when the element detaches from its panel.

Quick Lookup

Goal
How

Create an element

ParagonVisualElement.Create<MyElement>() or new MyElement()

Create with immediate GUI

ParagonVisualElement.CreateImmediate<MyElement>() or pass createImmediately: true

Bind a UXML template

Add [UxmlTemplate("TemplateName")] to the class

Query child elements

Q("name") or Q<Button>("name")

Toggle visibility

SetDisplay(true/false)

Check if ready

element.Initialized

Properties

Property
Type
Access
Description

Initialized

bool

public

true after OnInitialize() completes

Constructors

Parameter
Type
Default
Description

name

string

null

Element name. Defaults to GetType().Name if null

createImmediately

bool

false

If true, calls CreateGUI() in the constructor instead of waiting for panel attach

Methods

OnCreateGUI

Abstract callback invoked after the UXML template is cloned. Override to build the element's visual tree — query template elements, add children, wire event callbacks.

OnInitialize

Virtual callback invoked one frame after OnCreateGUI() via EditorApplication.delayCall.

OnDestroy

Virtual callback invoked when the element detaches from its panel.

Reset

Virtual method for resetting element state. Default implementation is empty.

GetTemplateAsset

Virtual method that resolves the UXML template. Default implementation reads the [UxmlTemplate] attribute from the class via reflection.

SetDisplay

Toggles element visibility by setting display style to Flex or None.

Q

Queries children by name.

Extension Points

Required Overrides

Method
Purpose

OnCreateGUI()

Build the element's visual tree — query template elements, add children

Optional Overrides

Method
Purpose

OnInitialize()

Deferred setup one frame after creation

OnDestroy()

Cleanup when element detaches from panel

Reset()

Reset element state (e.g., clear fields)

GetTemplateAsset()

Custom template resolution (default: reads [UxmlTemplate] attribute)

Implementation Requirements

When subclassing, you MUST:

  1. Override OnCreateGUI() — this is abstract

  2. Use a parameterless constructor (required for Create<T>() factory methods)

You SHOULD:

  • Add [UxmlTemplate("TemplateName")] to bind a UXML file

  • Query template elements in OnCreateGUI() using Q()

  • Use OnInitialize() for setup that requires the visual tree to be fully attached

  • Use SetDisplay() instead of directly manipulating style.display

You MUST NOT:

  • Query template children before OnCreateGUI() runs — the template is not yet cloned

  • Assume Initialized is true during OnCreateGUI() — it is set after OnInitialize()

Static Methods

Create<T>

Factory method that creates an element instance. GUI creation is deferred to panel attachment.

CreateImmediate<T>

Factory method that creates an element and immediately calls CreateGUI().

Common Pitfalls

circle-exclamation
circle-exclamation
circle-info

name defaults to the type name. If you don't pass a name to the constructor or factory, the element's name is set to GetType().Name. This makes Q() queries predictable in parent elements.

Examples

Basic Visual Element with Template

Programmatic Element (No Template)

Usage in a ParagonEditor

See Also

Last updated