> For the complete documentation index, see [llms.txt](https://dante-3.gitbook.io/dante-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dante-3.gitbook.io/dante-docs/modular-attachment-system/api-reference.md).

# API Reference

## UModularAttachmentFragment

```cpp
UCLASS(Abstract, Blueprintable, BlueprintType, EditInlineNew, DefaultToInstanced)
class UModularAttachmentFragment : public UObject
```

Base class for all fragments. Subclass to create custom attachment behaviors.

### Key Properties

| Property                  | Type                                  | Description                                         |
| ------------------------- | ------------------------------------- | --------------------------------------------------- |
| `FragmentTag`             | `FGameplayTag`                        | Tag identifier for this fragment instance           |
| `AttachedFragments`       | `TArray<UModularAttachmentFragment*>` | Child fragments (instanced, inline edit)            |
| `EditorGraphPosition`     | `FIntPoint`                           | *(Editor-only)* Node position in the fragment graph |
| `bHasEditorGraphPosition` | `bool`                                | *(Editor-only)* Whether graph position has been set |

### Virtual Methods (BlueprintNativeEvent)

```cpp
void CollectSoftRefs(TArray<FSoftObjectPath>& OutSoftReferences);
```

Called during **Phase 2**. Declare all soft references that must be streamed before apply.

```cpp
FSpawnedFragmentData ApplyToComponent(UModularAttachmentComponent* TargetComponent);
```

Called during **Phase 3**. Create runtime components. Return `FSpawnedFragmentData` with all spawned components.

```cpp
void RemoveFromComponent(UModularAttachmentComponent* TargetComponent,
                         const FSpawnedFragmentData& FragmentData);
```

Called on unload/swap. Destroy all components created in `ApplyToComponent`.

### Utility Methods

| Method                 | Returns                                | Description                                          |
| ---------------------- | -------------------------------------- | ---------------------------------------------------- |
| `GetParentFragment()`  | `UModularAttachmentFragment*`          | Walks Outer chain to find parent (null if top-level) |
| `GetOwnerDefinition()` | `UModularAttachmentDefinition*`        | Finds the containing definition asset                |
| `GetChildFragments()`  | `TArray<UModularAttachmentFragment*>&` | Returns `AttachedFragments` array                    |

### Parent Mesh Propagation

| Method                         | Returns            | Description                                                                                                              |
| ------------------------------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| `SetParentMeshComponent(Comp)` | `void`             | Sets the parent’s spawned mesh (called by `ApplyFragmentTree`)                                                           |
| `GetParentMeshComponent()`     | `USceneComponent*` | Returns the parent fragment’s mesh, or `nullptr` (BlueprintPure)                                                         |
| `GetSpawnedMeshComponent()`    | `USceneComponent*` | Override in subclasses — return your spawned mesh (BlueprintNativeEvent). Used for child propagation and editor outline. |

## UModularAttachmentFragment\_StaticMesh

```cpp
UCLASS(Blueprintable, BlueprintType, EditInlineNew, DefaultToInstanced)
class UModularAttachmentFragment_StaticMesh : public UModularAttachmentFragment
```

Spawns a `UStaticMeshComponent` attached to a socket.

### Key Properties

| Property                 | Type                          | Description                                |
| ------------------------ | ----------------------------- | ------------------------------------------ |
| `Mesh`                   | `TSoftObjectPtr<UStaticMesh>` | Static mesh asset (soft ref, async loaded) |
| `AttachSocketName`       | `FName`                       | Socket on the parent component             |
| `RelativeTransform`      | `FTransform`                  | Offset transform relative to socket        |
| `bGenerateOverlapEvents` | `bool`                        | Whether spawned mesh generates overlaps    |

### Behavior

* **CollectSoftRefs** — adds `Mesh` soft object path
* **ApplyToComponent** — creates `UStaticMeshComponent` via `Mesh.LoadSynchronous()`, attaches to parent mesh (via `GetParentMeshComponent()`) or socket, caches in `SpawnedMeshComp`
* **GetSpawnedMeshComponent** — returns `SpawnedMeshComp` (used for child propagation and editor outline)
* **RemoveFromComponent** — destroys the spawned component

## UModularAttachmentFragment\_SkeletalMesh

```cpp
UCLASS(Blueprintable, BlueprintType, EditInlineNew, DefaultToInstanced)
class UModularAttachmentFragment_SkeletalMesh : public UModularAttachmentFragment
```

Spawns a `USkeletalMeshComponent` with optional animation and leader pose sync.

### Key Properties

| Property            | Type                            | Description                                    |
| ------------------- | ------------------------------- | ---------------------------------------------- |
| `Mesh`              | `TSoftObjectPtr<USkeletalMesh>` | Skeletal mesh asset (soft ref)                 |
| `AnimClass`         | `TSoftClassPtr<UAnimInstance>`  | Optional animation Blueprint class (soft ref)  |
| `AttachSocketName`  | `FName`                         | Socket to attach to                            |
| `RelativeTransform` | `FTransform`                    | Offset transform                               |
| `bUseLeaderPose`    | `bool`                          | If true, syncs bones with parent skeletal mesh |

### Behavior

* **CollectSoftRefs** — adds `Mesh` and `AnimClass` soft paths
* **ApplyToComponent** — creates `USkeletalMeshComponent` via `Mesh.LoadSynchronous()`, sets anim class via `AnimClass.LoadSynchronous()`, attaches to parent mesh (via `GetParentMeshComponent()`) or socket, optionally sets leader pose, caches in `SpawnedSkelComp`
* **GetSpawnedMeshComponent** — returns `SpawnedSkelComp` (used for child propagation and editor outline)
* **RemoveFromComponent** — destroys the spawned component

## UModularAttachmentDefinition

```cpp
UCLASS(Blueprintable, BlueprintType)
class UModularAttachmentDefinition : public UPrimaryDataAsset
```

Data asset that composes multiple fragments into a complete attachment.

### Key Properties

| Property              | Type                                  | Description                                                  |
| --------------------- | ------------------------------------- | ------------------------------------------------------------ |
| `AttachmentFragments` | `TArray<UModularAttachmentFragment*>` | Ordered list of top-level fragments (instanced, inline edit) |

### Key Methods

| Method                        | Returns           | Description                                                         |
| ----------------------------- | ----------------- | ------------------------------------------------------------------- |
| `GetPrimaryAssetId()`         | `FPrimaryAssetId` | Returns `"AttachmentDefinition:<AssetName>"`                        |
| `CollectAllSoftRefs(OutRefs)` | `void`            | Recursively walks all fragments + children, collects all soft paths |

### Editor Callbacks

| Method                     | Description                                                                       |
| -------------------------- | --------------------------------------------------------------------------------- |
| `PostEditChangeProperty()` | Calls `OnFragmentChanged()` → refreshes all live components using this definition |

## UModularAttachmentComponent

```cpp
UCLASS(Blueprintable, BlueprintType,
       ClassGroup=("Modular Attachment System"),
       meta=(BlueprintSpawnableComponent))
class UModularAttachmentComponent : public USceneComponent
```

Runtime mount point. Add to any actor to create an attachment slot.

### Key Properties

| Property                    | Type                                           | Description                                        |
| --------------------------- | ---------------------------------------------- | -------------------------------------------------- |
| `AttachmentDefinitionAsset` | `TSoftObjectPtr<UModularAttachmentDefinition>` | Definition to load (editor or runtime)             |
| `ComponentTag`              | `FGameplayTag`                                 | Slot identifier for registration and event routing |

### Key Delegates

| Delegate                    | Signature                     | Fires When                                          |
| --------------------------- | ----------------------------- | --------------------------------------------------- |
| `OnAttachmentEvent`         | `FOnAttachmentEvent(Payload)` | Event broadcast targets this component's tag        |
| `OnAttachmentLoadCompleted` | `FOnAttachmentEvent(Payload)` | Definition + all fragments fully loaded and applied |

### Key Methods — Load / Unload

| Method                          | Description                                                    |
| ------------------------------- | -------------------------------------------------------------- |
| `LoadAttachment()`              | Begin async load. Deduped via subsystem ref-counted cache.     |
| `UnloadAttachment()`            | Remove all fragment components, decrement subsystem ref count. |
| `SwapAttachment(NewDefinition)` | Atomic unload → load.                                          |

### Key Methods — State Queries

| Method                 | Returns                | Description                   |
| ---------------------- | ---------------------- | ----------------------------- |
| `IsAttachmentLoaded()` | `bool`                 | True if `LoadState == Loaded` |
| `GetLoadState()`       | `EAttachmentLoadState` | Current load state enum       |

### Key Methods — Fragment Access

| Method                                         | Returns                       | Description                                                                                   |
| ---------------------------------------------- | ----------------------------- | --------------------------------------------------------------------------------------------- |
| `GetFragmentByTag(Tag)`                        | `UModularAttachmentFragment*` | Find fragment object by `FragmentTag`                                                         |
| `GetSpawnedComponentsByFragmentTag(Tag)`       | `TArray<UActorComponent*>`    | All runtime components spawned by a fragment                                                  |
| `GetSpawnedComponentByFragmentTag(Tag, Class)` | `UActorComponent*`            | First component matching class — BP pin type follows `Class` via `DeterminesOutputType`       |
| `GetMeshComponentByFragmentTag(Tag)`           | `UMeshComponent*`             | First mesh component (static or skeletal) — use for `SetMaterial` and other mesh-agnostic ops |
| `GetStaticMeshComponentByFragmentTag(Tag)`     | `UStaticMeshComponent*`       | Shorthand — first static mesh component for a fragment                                        |
| `GetSkeletalMeshComponentByFragmentTag(Tag)`   | `USkeletalMeshComponent*`     | Shorthand — first skeletal mesh component for a fragment                                      |
| `GetTypedSpawnedComponent<T>(Tag)`             | `T*`                          | *(C++ only)* Template convenience, returns first component castable to `T`                    |

### Lifecycle

| Phase                     | Action                                                              |
| ------------------------- | ------------------------------------------------------------------- |
| `BeginPlay`               | Auto-calls `LoadAttachment()` if `AttachmentDefinitionAsset` is set |
| `EndPlay`                 | Auto-calls `UnloadAttachment()`                                     |
| `OnRegister` *(Editor)*   | `ApplyEditorPreview()` — sync loads and applies fragments           |
| `OnUnregister` *(Editor)* | `ClearEditorPreview()` — destroys preview components                |

## UModularAttachmentSubsystem

```cpp
class UModularAttachmentSubsystem : public UWorldSubsystem
```

Central coordinator for asset streaming, tag registry, and event broadcasting. One instance per `UWorld`.

### Asset Streaming

| Method                               | Description                                                                                |
| ------------------------------------ | ------------------------------------------------------------------------------------------ |
| `RequestLoad(Definition, Component)` | Start three-phase load pipeline. Ref-counted — same definition shared across N components. |
| `ReleaseLoad(Definition, Component)` | Decrement ref count. When 0, schedules deferred unload on next tick.                       |

### Tag Registry

| Method                                | Description                                                      |
| ------------------------------------- | ---------------------------------------------------------------- |
| `RegisterComponent(Tag, Component)`   | Add component to `Tag→Components` map                            |
| `UnregisterComponent(Tag, Component)` | Remove component from map                                        |
| `GetComponentsByTag(Tag)`             | Returns all live components under a tag (auto-cleans stale ptrs) |

### Bulk Operations

| Method             | Description                                                        |
| ------------------ | ------------------------------------------------------------------ |
| `UnloadAll()`      | Release all cached assets immediately                              |
| `UnloadByTag(Tag)` | Unload only components registered under a specific tag             |
| `ReloadAll()`      | Cancel all handles, re-request load for every registered component |

### Event Broadcasting

```cpp
UFUNCTION(BlueprintCallable, Category = "Attachment")
void BroadcastToTag(FGameplayTag TargetTag, const FAttachmentEventPayload& Payload);
```

Routes the payload to all components registered under `TargetTag`. Fires both:

* `OnTagEventNative` — C++ global delegate
* `Component→OnAttachmentEvent` — per-component Blueprint delegate

## UModularAttachmentFunctionLibrary

```cpp
class UModularAttachmentFunctionLibrary : public UBlueprintFunctionLibrary
```

Static utility functions accessible from any Blueprint.

### Functions

| Function                                            | Returns                                | Description                                  |
| --------------------------------------------------- | -------------------------------------- | -------------------------------------------- |
| `GetAttachmentComponents(Actor)`                    | `TArray<UModularAttachmentComponent*>` | Find all attachment components on an actor   |
| `GetAttachmentComponentByTag(Actor, SlotTag)`       | `UModularAttachmentComponent*`         | Find component matching a `ComponentTag`     |
| `GetFragmentByTag(Component, FragmentTag)`          | `UModularAttachmentFragment*`          | Find a fragment by tag on a component        |
| `GetSpawnedComponentsByFragmentTag(Component, Tag)` | `TArray<UActorComponent*>`             | Get runtime components spawned by a fragment |

> The component itself also exposes `GetStaticMeshComponentByFragmentTag`, `GetSkeletalMeshComponentByFragmentTag`, and the generic `GetSpawnedComponentByFragmentTag(Tag, Class)` — see [UModularAttachmentComponent](#umodularattachmentcomponent).

## UAsyncTask\_EquipAttachment

```cpp
UCLASS()
class UAsyncTask_EquipAttachment : public UBlueprintAsyncActionBase
```

Blueprint async action node for equipping attachments at runtime.

### Factory Method

```cpp
static UAsyncTask_EquipAttachment* EquipAttachment(
    UObject* WorldContextObject,
    AActor* TargetActor,
    TSoftObjectPtr<UModularAttachmentDefinition> Definition,
    FGameplayTag SlotTag);
```

### Parameters

| Parameter            | Description                                  |
| -------------------- | -------------------------------------------- |
| `WorldContextObject` | Any world-context object (auto-filled in BP) |
| `TargetActor`        | Actor to equip the attachment on             |
| `Definition`         | Definition asset to load and apply           |
| `SlotTag`            | Which slot to use (`ComponentTag` match)     |

### Output Pins

| Pin          | Fires When                                            |
| ------------ | ----------------------------------------------------- |
| `OnEquipped` | Definition loaded, fragments applied, component valid |
| `OnFailed`   | Load failed, null definition, or invalid target actor |

### Flow

1. Searches `TargetActor` for component with matching `ComponentTag`
2. If not found → creates and registers a new component
3. Calls `SwapAttachment(Definition)`
4. Waits for `OnAttachmentLoadCompleted`
5. Fires `OnEquipped` or `OnFailed`

## Structs & Enums

### EAttachmentLoadState

```cpp
UENUM(BlueprintType)
enum class EAttachmentLoadState : uint8
{
    NotLoaded,
    Loading,
    Loaded,
    Failed
};
```

### FSpawnedFragmentData

| Field               | Type                                         | Description                                                             |
| ------------------- | -------------------------------------------- | ----------------------------------------------------------------------- |
| `FragmentTag`       | `FGameplayTag`                               | Which fragment spawned these components                                 |
| `OwnerFragment`     | `TWeakObjectPtr<UModularAttachmentFragment>` | Back-pointer to the fragment that produced this data (used for cleanup) |
| `SpawnedComponents` | `TArray<TWeakObjectPtr<UActorComponent>>`    | All runtime components created                                          |

Returned by `ApplyToComponent()` and passed to `RemoveFromComponent()` for cleanup.

### FAttachmentEventPayload

| Field        | Type                        | Description                                                     |
| ------------ | --------------------------- | --------------------------------------------------------------- |
| `EventTag`   | `FGameplayTag`              | What happened (e.g., `ModularAttachment.Event.Aim`)             |
| `TargetTag`  | `FGameplayTag`              | Who receives it (e.g., `ModularAttachment.Slot.Optic`)          |
| `Instigator` | `UObject*`                  | Who triggered the event                                         |
| `Values`     | `TMap<FGameplayTag, float>` | Named numeric data (e.g., `ModularAttachment.Value.Zoom → 4.0`) |

## Delegates

### FOnAttachmentEvent — Dynamic Multicast

```cpp
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(
    FOnAttachmentEvent,
    const FAttachmentEventPayload&, Payload);
```

Blueprint-bindable. Used by:

* `UModularAttachmentComponent::OnAttachmentEvent` — per-component event reception
* `UModularAttachmentComponent::OnAttachmentLoadCompleted` — load completion

### FOnAttachmentTagEvent — Native Multicast

```cpp
DECLARE_MULTICAST_DELEGATE_TwoParams(
    FOnAttachmentTagEvent,
    FGameplayTag /*TargetTag*/,
    const FAttachmentEventPayload& /*Payload*/);
```

C++-only delegate on the subsystem. Fires for every `BroadcastToTag()` call — useful for global listeners.

## Log Channel

```cpp
DECLARE_LOG_CATEGORY_EXTERN(LogModularAttachmentSystem, Log, All);
```

Used for asset load warnings, state transition errors, fragment validation failures, and subsystem registration traces.

**Filtering:**

```ini
; DefaultEngine.ini or console command:
LogModularAttachmentSystem Verbose
LogModularAttachmentSystem Warning
```
