feat: Add Blueprint Limitations & Workarounds documentation and update GameTagRegistry spec
This commit is contained in:
@@ -13,6 +13,7 @@ Single Source of Truth for the Unreal Engine 5.5-5.7 Blueprint-based Modular Gam
|
|||||||
- **Animation:** GASP Motion Matching + overlay notifies. Full catalog in [`docs/architecture/animation-catalog.md`](docs/architecture/animation-catalog.md)
|
- **Animation:** GASP Motion Matching + overlay notifies. Full catalog in [`docs/architecture/animation-catalog.md`](docs/architecture/animation-catalog.md)
|
||||||
- **Audio:** 150+ sound triggers + 14-surface material table. Full catalog in [`docs/architecture/sound-catalog.md`](docs/architecture/sound-catalog.md)
|
- **Audio:** 150+ sound triggers + 14-surface material table. Full catalog in [`docs/architecture/sound-catalog.md`](docs/architecture/sound-catalog.md)
|
||||||
- **Networking:** Server-authoritative replication model. Full architecture in [`docs/architecture/multiplayer-networking.md`](docs/architecture/multiplayer-networking.md)
|
- **Networking:** Server-authoritative replication model. Full architecture in [`docs/architecture/multiplayer-networking.md`](docs/architecture/multiplayer-networking.md)
|
||||||
|
- **BP Limitations:** Catalog of C++-only UE5 functions + 100% Blueprint workarounds. See [`docs/architecture/blueprint-limitations-workarounds.md`](docs/architecture/blueprint-limitations-workarounds.md)
|
||||||
|
|
||||||
## Directory Structure
|
## Directory Structure
|
||||||
```
|
```
|
||||||
@@ -92,7 +93,7 @@ docs/
|
|||||||
09-ai-systems.md # AI, perception & encounters explained
|
09-ai-systems.md # AI, perception & encounters explained
|
||||||
10-adaptive-systems.md # Adaptive environment & atmosphere explained
|
10-adaptive-systems.md # Adaptive environment & atmosphere explained
|
||||||
11-16-systems.md # Meta, Settings, Polish, Data Assets, Input, State explained
|
11-16-systems.md # Meta, Settings, Polish, Data Assets, Input, State explained
|
||||||
architecture/ # Architecture & Design Documents (7 files)
|
architecture/ # Architecture & Design Documents (8 files)
|
||||||
bpc-statemanager.md # BPC_StateManager full spec + Chooser Table Audit
|
bpc-statemanager.md # BPC_StateManager full spec + Chooser Table Audit
|
||||||
metasounds-audio-system.md # MetaSounds audio architecture (mix buses, room zones, settings)
|
metasounds-audio-system.md # MetaSounds audio architecture (mix buses, room zones, settings)
|
||||||
animation-catalog.md # Animation requirements for all 135 systems
|
animation-catalog.md # Animation requirements for all 135 systems
|
||||||
@@ -100,6 +101,7 @@ docs/
|
|||||||
enhanced-input-system.md # Enhanced Input System architecture
|
enhanced-input-system.md # Enhanced Input System architecture
|
||||||
hud-overview.md # HUD system architecture — 14 widgets, wiring, integration points
|
hud-overview.md # HUD system architecture — 14 widgets, wiring, integration points
|
||||||
multiplayer-networking.md # Multiplayer networking architecture — authority model, RPCs, prediction
|
multiplayer-networking.md # Multiplayer networking architecture — authority model, RPCs, prediction
|
||||||
|
blueprint-limitations-workarounds.md # UE5 C++-only functions + 100% Blueprint workarounds (NEW)
|
||||||
CLEAN_SLATE_PLAN.md # Clean slate refactoring plan
|
CLEAN_SLATE_PLAN.md # Clean slate refactoring plan
|
||||||
reports/ # Condensed audit reports
|
reports/ # Condensed audit reports
|
||||||
blueprint_condensed_summary.md # ASK agent audit of all 129 files
|
blueprint_condensed_summary.md # ASK agent audit of all 129 files
|
||||||
@@ -108,7 +110,7 @@ docs/
|
|||||||
enhanced-input-system.md
|
enhanced-input-system.md
|
||||||
bpc-statemanager.md # NEW — State Manager implementation checklist
|
bpc-statemanager.md # NEW — State Manager implementation checklist
|
||||||
```
|
```
|
||||||
**Total: 135 numbered Blueprint files + 5 enums + 5 Data Assets + TEMPLATE.md + AUDIT_REPORT.md + INDEX.md + 11 developer docs + 7 architecture docs + 1 audit report = 165 files in 18 directory groups**
|
**Total: 135 numbered Blueprint files + 5 enums + 5 Data Assets + TEMPLATE.md + AUDIT_REPORT.md + INDEX.md + 11 developer docs + 8 architecture docs + 1 audit report = 166 files in 18 directory groups**
|
||||||
|
|
||||||
## Naming Conventions
|
## Naming Conventions
|
||||||
| Prefix | Type |
|
| Prefix | Type |
|
||||||
@@ -190,6 +192,7 @@ Each file in `docs/blueprints/` follows the template defined in [`docs/blueprint
|
|||||||
3. The relevant [`docs/developer/`](docs/developer/) category document — if the change modifies a system's behavior, dependencies, or implementation pattern
|
3. The relevant [`docs/developer/`](docs/developer/) category document — if the change modifies a system's behavior, dependencies, or implementation pattern
|
||||||
4. [`docs/architecture/animation-catalog.md`](docs/architecture/animation-catalog.md) — if the change adds/modifies animation requirements
|
4. [`docs/architecture/animation-catalog.md`](docs/architecture/animation-catalog.md) — if the change adds/modifies animation requirements
|
||||||
5. [`docs/architecture/sound-catalog.md`](docs/architecture/sound-catalog.md) — if the change adds/modifies audio triggers or surfaces
|
5. [`docs/architecture/sound-catalog.md`](docs/architecture/sound-catalog.md) — if the change adds/modifies audio triggers or surfaces
|
||||||
|
6. [`docs/architecture/blueprint-limitations-workarounds.md`](docs/architecture/blueprint-limitations-workarounds.md) — if the change uses a new C++-only UE5 function that needs a Blueprint workaround
|
||||||
|
|
||||||
No PR is accepted without these files being current. This ensures the animator, sound designer, developers, and all team members always have an up-to-date reference.
|
No PR is accepted without these files being current. This ensures the animator, sound designer, developers, and all team members always have an up-to-date reference.
|
||||||
|
|
||||||
|
|||||||
188
docs/architecture/blueprint-limitations-workarounds.md
Normal file
188
docs/architecture/blueprint-limitations-workarounds.md
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
# UE5 Blueprint Limitations & Workarounds — Modular Game Framework
|
||||||
|
|
||||||
|
**Version:** 1.0 | **Generated:** 2026-05-19
|
||||||
|
|
||||||
|
This document catalogs all UE5 engine functions that are C++ only (not exposed to Blueprints) which the framework's specification files reference, and provides 100% Blueprint workarounds for each.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. GameplayTags Limitations
|
||||||
|
|
||||||
|
### 1.1 `Get All Gameplay Tags` (C++ Only)
|
||||||
|
|
||||||
|
**Engine Function:** `UGameplayTagsManager::Get().RequestAllGameplayTags()`
|
||||||
|
**UE5 Node:** Does NOT exist in Blueprint
|
||||||
|
**Files Affected:** `01_GI_GameTagRegistry.md`, any system that needs to enumerate all tags
|
||||||
|
|
||||||
|
**Blueprint Workaround — Data Table Proxy:**
|
||||||
|
|
||||||
|
1. Create a Data Table: `DT_ProjectTags` with Row Structure = `GameplayTagTableRow`
|
||||||
|
2. Populate it with all framework tags (mirrors `DefaultGameplayTags.ini`)
|
||||||
|
3. Register in Project Settings → GameplayTags → Gameplay Tag Table List
|
||||||
|
4. In Blueprint: use `Get Data Table Row Names` → `ForEachLoop` → `Get Data Table Row` → extract `Tag` field
|
||||||
|
5. This provides a complete tag list without C++
|
||||||
|
|
||||||
|
**Trade-off:** Manual maintenance. Adding new tags requires updating both the `.ini` file AND the Data Table. Mitigation: use `ExportTagNamespace()` to audit for discrepancies.
|
||||||
|
|
||||||
|
### 1.2 `RequestGameplayTag(String)` → GameplayTag (C++ Only)
|
||||||
|
|
||||||
|
**Engine Function:** `UGameplayTagsManager::Get().RequestGameplayTag(FName)`
|
||||||
|
**UE5 Node:** Not directly available. The closest BP node is `Make Literal Gameplay Tag`.
|
||||||
|
|
||||||
|
**Blueprint Workaround — Multiple options:**
|
||||||
|
|
||||||
|
**Option A:** `Make Literal Gameplay Tag` — creates a GameplayTag from a literal string at compile time. Works only if the tag exists in the tag table.
|
||||||
|
**Option B:** `Is Gameplay Tag Valid` — for validation only (returns boolean).
|
||||||
|
**Option C:** `Get Gameplay Tag from Name` (available in some UE5 versions via `GameplayTagsBlueprintLibrary`).
|
||||||
|
|
||||||
|
**Recommendation:** For `ValidateTag()` in `DA_GameTagRegistry`, use `Is Gameplay Tag Valid`. For runtime tag creation from strings, use `Make Literal Gameplay Tag` with fallback validation.
|
||||||
|
|
||||||
|
### 1.3 `UGameplayTagsManager::Get()` Singleton (C++ Only)
|
||||||
|
|
||||||
|
**Engine Pattern:** `UGameplayTagsManager::Get()` returns the singleton.
|
||||||
|
**UE5 Node:** Not available. The manager is accessed implicitly through GameplayTags Blueprint nodes.
|
||||||
|
|
||||||
|
**Blueprint Workaround:** Never reference the manager directly. Use the Blueprint nodes listed above. All tag operations (match, compare, validate) have Blueprint equivalents.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Subsystem Access Limitations
|
||||||
|
|
||||||
|
### 2.1 Static Function Library Accessor Pattern (Requires C++ for Clean Implementation)
|
||||||
|
|
||||||
|
**Pattern:** `FL_GameUtilities::GetUIManager()`, `FL_GameUtilities::GetInputManager()`
|
||||||
|
**Issue:** BlueprintFunctionLibrary static functions require C++ implementation for the static accessor pattern. In pure Blueprint, you cannot create a truly static accessor with clean syntax.
|
||||||
|
|
||||||
|
**Blueprint Workaround:**
|
||||||
|
|
||||||
|
Instead of `FL_GameUtilities::GetUIManager()`, use:
|
||||||
|
```
|
||||||
|
Get Game Instance → Get Subsystem (SS_UIManager Class)
|
||||||
|
```
|
||||||
|
OR create a Blueprint Macro Library with a macro that wraps the subsystem lookup.
|
||||||
|
|
||||||
|
**Files Affected:** `02_FL_GameUtilities.md`, `44_SS_UIManager.md`, `128_SS_EnhancedInputManager.md`
|
||||||
|
|
||||||
|
**Recommendation:** For a pure BP framework, document the direct `Get Game Instance → Get Subsystem` pattern. The FL_GameUtilities static accessors can be kept as documentation of the intent, but the implementation guide should show the direct BP node path.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Data Asset Limitations
|
||||||
|
|
||||||
|
### 3.1 `OnAssetLoaded` / `BeginPlay` on Data Assets (Not Available)
|
||||||
|
|
||||||
|
**Engine Behavior:** `UPrimaryDataAsset` does not have `BeginPlay`, `Tick`, or event graphs. It's a pure data container.
|
||||||
|
**Files Affected:** `01_GI_GameTagRegistry.md`, all DA_* specs
|
||||||
|
|
||||||
|
**Blueprint Workaround:** Move initialization and validation logic to an owning system:
|
||||||
|
|
||||||
|
- **GameInstance** (`GI_GameFramework.Init()`) — load and validate Data Assets at game startup
|
||||||
|
- **Subsystem** (`BPC_StateManager.BeginPlay()`) — validate configuration during component init
|
||||||
|
- **Editor Utility** — create an Editor Utility Widget/Blueprint for pre-game validation
|
||||||
|
|
||||||
|
**Pattern:**
|
||||||
|
```
|
||||||
|
[In GI_GameFramework.Init()]
|
||||||
|
Load DA_GameTagRegistry (hard reference)
|
||||||
|
Call DA_GameTagRegistry.ValidateAllTags()
|
||||||
|
If failed → Print Error, optionally halt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 `FPrimaryAssetId` / `FPrimaryAssetType` in Variables (Blueprint Types Exist)
|
||||||
|
|
||||||
|
**Engine Types:** `FPrimaryAssetId`, `FPrimaryAssetType`
|
||||||
|
**Blueprint Equivalent:** `Primary Asset Id` (variable type), `Primary Asset Type` (variable type)
|
||||||
|
|
||||||
|
**Workaround:** Use the Blueprint variable types `Primary Asset Id` and `Primary Asset Type`. The `Async Load Primary Asset` node works in Blueprint. Asset Manager configuration (types, labels) is done in `Project Settings → Asset Manager` or `DefaultGame.ini`.
|
||||||
|
|
||||||
|
**Files Affected:** `07_DA_ItemData.md`, `118_DA_DataAssetArchitecture.md`, `119_DA_EncounterData.md`, `123_DA_ObjectiveData.md`, `27_BPC_CollectibleTracker.md`
|
||||||
|
|
||||||
|
### 3.3 `AssetManager` / `StreamableManager` Async Loading (Blueprint Nodes Exist)
|
||||||
|
|
||||||
|
**Blueprint Nodes Available:**
|
||||||
|
- `Async Load Primary Asset` — async loading with callback
|
||||||
|
- `Get Asset Manager` — returns the Asset Manager subsystem
|
||||||
|
- `Get Primary Asset Id List` — enumerates registered assets
|
||||||
|
|
||||||
|
**⚠️ Limitation:** `UAssetManager::GetPrimaryAssetPath()` and some query functions are C++ only. For pure BP, use `Async Load Primary Asset` by `Primary Asset Id`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Animation & Physics Limitations
|
||||||
|
|
||||||
|
### 4.1 Motion Warping Target Calculation (Blueprint Available)
|
||||||
|
|
||||||
|
**UE5 Node:** `Add Motion Warping Target`, `Calculate Motion Warping Target` — these exist in Blueprint.
|
||||||
|
|
||||||
|
**Files Affected:** `21_BPC_ContextualTraversalSystem.md` — no workaround needed, standard BP nodes available.
|
||||||
|
|
||||||
|
### 4.2 Physics Constraint Component Creation at Runtime (Blueprint Available)
|
||||||
|
|
||||||
|
**UE5 Node:** `Add Physics Constraint Component`, `Set Constrained Components` — available in Blueprint.
|
||||||
|
|
||||||
|
**Files Affected:** `22_BPC_PhysicsDragSystem.md` — no workaround needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Input System Limitations
|
||||||
|
|
||||||
|
### 5.1 Enhanced Input Subsystem Access (Blueprint Available)
|
||||||
|
|
||||||
|
**UE5 Node:** `Get Enhanced Input Local Player Subsystem`, `Add Mapping Context`, `Remove Mapping Context` — available in Blueprint.
|
||||||
|
|
||||||
|
**Files Affected:** `128_SS_EnhancedInputManager.md` — no workaround needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Debug & Development Limitations
|
||||||
|
|
||||||
|
### 6.1 `DO_CHECK` / Preprocessor Stripping for Shipping (Requires C++ or Project Setting)
|
||||||
|
|
||||||
|
**Issue:** C++ functions can use `#if !UE_BUILD_SHIPPING` to strip code from shipping builds. Blueprint functions can't do this natively.
|
||||||
|
|
||||||
|
**Blueprint Workaround:**
|
||||||
|
|
||||||
|
**Option A:** Editor-only Blueprint nodes — some nodes have an "Editor Only" checkbox. Mark debug functions as editor-only.
|
||||||
|
**Option B:** `Is Editor Build` branch — branch on `Is Editor` or development build check before executing debug logic.
|
||||||
|
**Option C:** Debug object channel — create a separate Blueprint with all debug logic; don't include it in shipping builds.
|
||||||
|
|
||||||
|
**Files Affected:** `02_FL_GameUtilities.md`, `107_BPC_DevCheatManager.md`, `113_WBP_DebugMenu.md`
|
||||||
|
|
||||||
|
**Recommendation:** Use `Is Editor Build` branch before all debug logic. Accept that some debug code will exist in shipping builds but be inactive at runtime.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Quick Reference: Node Availability Map
|
||||||
|
|
||||||
|
| Engine C++ Function | Available in BP? | BP Node Name | Workaround Needed? |
|
||||||
|
|---------------------|-----------------|--------------|-------------------|
|
||||||
|
| `UGameplayTagsManager::RequestAllGameplayTags()` | ❌ No | N/A | **Yes** — Data Table proxy |
|
||||||
|
| `UGameplayTagsManager::RequestGameplayTag()` | ⚠️ Partial | `Make Literal Gameplay Tag` | Use `Is Gameplay Tag Valid` for validation |
|
||||||
|
| `UGameplayTagsManager::Get()` | ❌ No | N/A | Never needed — use BP tag nodes |
|
||||||
|
| `GetSubsystem<T>()` | ✅ Yes | `Get Subsystem (Class)` | No |
|
||||||
|
| `GetGameInstance()` | ✅ Yes | `Get Game Instance` | No |
|
||||||
|
| `UAssetManager::Get()` | ✅ Yes | `Get Asset Manager` | No |
|
||||||
|
| `StreamableManager::RequestAsyncLoad()` | ✅ Yes | `Async Load Primary Asset` | No |
|
||||||
|
| `CharacterMovementComponent` functions | ✅ Yes | Various BP nodes | No |
|
||||||
|
| `PlayerCameraManager` functions | ✅ Yes | `Get Player Camera Manager` | No |
|
||||||
|
| Enhanced Input functions | ✅ Yes | `Get Enhanced Input Local Player Subsystem` | No |
|
||||||
|
| Physics Constraint functions | ✅ Yes | `Add Physics Constraint Component` | No |
|
||||||
|
| `#if !UE_BUILD_SHIPPING` preprocessor | ❌ No | N/A | Use `Is Editor Build` branch |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Implementation Rules for BP-Only Framework
|
||||||
|
|
||||||
|
When writing or updating Blueprint spec files, follow these rules to avoid C++-only references:
|
||||||
|
|
||||||
|
1. **Never reference `UGameplayTagsManager::Get()`** — use `Get Tag Display Name`, `Is Gameplay Tag Valid`, `Make Literal Gameplay Tag`.
|
||||||
|
2. **Never reference `Get All Gameplay Tags`** — use the Data Table proxy pattern (`DT_ProjectTags` → `Get Data Table Row Names`).
|
||||||
|
3. **Never use `FPrimaryAssetId` as a type name** — use `Primary Asset Id` (Blueprint type).
|
||||||
|
4. **Never use `TSoftObjectPtr` as a type name** — use `Soft Object Reference` (Blueprint type).
|
||||||
|
5. **Never put logic in Data Assets** — move initialization/validation to GameInstance, Subsystem, or Editor Utility.
|
||||||
|
6. **Never use C++ include guards or preprocessor** — use `Is Editor Build` for conditional logic.
|
||||||
|
7. **Prefer `Get Game Instance → Get Subsystem(Class)`** over static helper functions for subsystem access.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Blueprint Limitations & Workarounds v1.0 — Maintained alongside framework specs. Update when new engine limitations are discovered.*
|
||||||
@@ -54,16 +54,16 @@ None. The registry is a flat collection of tag declarations.
|
|||||||
|
|
||||||
| Name | Inputs | Outputs | Category | Description |
|
| Name | Inputs | Outputs | Category | Description |
|
||||||
|------|--------|---------|----------|-------------|
|
|------|--------|---------|----------|-------------|
|
||||||
| `GetAllRegisteredTags` | — | `Array<FGameplayTag>` | Query | Returns all tags defined in this registry (reads from the project's tag table) |
|
| `GetAllRegisteredTags` | — | `Array<FGameplayTag>` | Query | Reads tags from `DT_ProjectTags` Data Table (see Section 14 for UE5 BP workaround) |
|
||||||
| `GetTagDisplayName` | `Tag: FGameplayTag` | `FText` | Query | Returns the human-readable display name from the tag table |
|
| `GetTagDisplayName` | `Tag: FGameplayTag` | `Text` | Query | Returns the human-readable display name via `Get Tag Display Name` node |
|
||||||
| `ValidateTag` | `Tag: FGameplayTag` | `bool` | Validation | Returns `true` if the tag exists in the project's registered tag table |
|
| `ValidateTag` | `Tag: FGameplayTag` | `Boolean` | Validation | Returns `true` if the tag is valid via `Is Gameplay Tag Valid` node |
|
||||||
|
|
||||||
### 6.2 Blueprint Callable Functions
|
### 6.2 Blueprint Callable Functions
|
||||||
|
|
||||||
| Name | Inputs | Outputs | Category | Description |
|
| Name | Inputs | Outputs | Category | Description |
|
||||||
|------|--------|---------|----------|-------------|
|
|------|--------|---------|----------|-------------|
|
||||||
| `LogAllTags` | — | — | Debug | Prints all registered tags to the output log (Editor-only) |
|
| `LogAllTags` | — | — | Debug | Prints all tags (from Data Table) to the output log (Editor-only) |
|
||||||
| `ExportTagNamespace` | `NamespacePrefix: FString` | `FString` | Tooling | Exports all tags matching a namespace prefix as a formatted string (for documentation generation) |
|
| `ExportTagNamespace` | `NamespacePrefix: String` | `String` | Tooling | Exports all tags matching a namespace prefix as a formatted string | |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -75,17 +75,82 @@ None. This Data Asset is passive — it has no runtime events.
|
|||||||
|
|
||||||
## 8. Overridden Events
|
## 8. Overridden Events
|
||||||
|
|
||||||
| Event | Description |
|
**Note:** Data Assets do NOT have `BeginPlay`, `Tick`, or `OnAssetLoaded` in Blueprint. All validation logic should be called externally from a GameInstance or Subsystem during initialization.
|
||||||
|-------|-------------|
|
|
||||||
| `OnAssetLoaded` | Logs a validation warning if no Gameplay Tags are registered in the project |
|
|
||||||
| `PreSaveGameplayTags` | Ensures the tag table is synchronised with the asset's documented namespaces |
|
|
||||||
|
|
||||||
---
|
### Initialization Pattern (called externally):
|
||||||
|
```
|
||||||
|
[In GI_GameFramework.Init() or BPC_StateManager.BeginPlay:]
|
||||||
|
├─► Load DA_GameTagRegistry (hard reference or Get Data Asset)
|
||||||
|
├─► Call DA_GameTagRegistry.GetAllRegisteredTags()
|
||||||
|
├─► Array Length == 0?
|
||||||
|
│ ├─► Yes → Print Warning: "No tags in DT_ProjectTags! Framework tags are unregistered."
|
||||||
|
│ └─► No → Log: "N tags registered."
|
||||||
|
└─► Optional: call LogAllTags() for debug output
|
||||||
|
```
|
||||||
|
|
||||||
## 9. Blueprint Graph Logic
|
## 9. Blueprint Graph Logic
|
||||||
|
|
||||||
### 9.1 Initialisation Flow
|
### 9.1 GetAllRegisteredTags (Data Table Proxy)
|
||||||
|
|
||||||
|
**⚠️ UE5 Limitation:** `UGameplayTagsManager::RequestAllGameplayTags()` is C++ only — not exposed to Blueprints. This function uses a **Data Table proxy** instead. Tags must be registered in `DT_ProjectTags` which mirrors `DefaultGameplayTags.ini`.
|
||||||
|
|
||||||
|
```
|
||||||
|
[Function: GetAllRegisteredTags] → Array<GameplayTag>
|
||||||
|
Step 1: Get Data Table Row Names (DT_ProjectTags)
|
||||||
|
Step 2: Create empty Array<GameplayTag> → LocalTags
|
||||||
|
Step 3: ForEachLoop (RowNames):
|
||||||
|
├─► Get Data Table Row (DT_ProjectTags, RowName)
|
||||||
|
│ → Break the GameplayTagTableRow struct → get "Tag" field
|
||||||
|
├─► Add "Tag" to LocalTags array
|
||||||
|
Step 4: Return LocalTags
|
||||||
|
```
|
||||||
|
|
||||||
|
**Node Search:** `Get Data Table Row Names`, `ForEachLoop`, `Get Data Table Row`, `Break GameplayTagTableRow`, `Add`
|
||||||
|
|
||||||
|
### 9.2 ValidateTag
|
||||||
|
|
||||||
|
**⚠️ UE5 Limitation:** `UGameplayTagsManager::RequestGameplayTag()` is not a direct Blueprint node. Use `Is Gameplay Tag Valid` instead.
|
||||||
|
|
||||||
|
```
|
||||||
|
[Function: ValidateTag(Tag)] → Boolean
|
||||||
|
Step 1: Is Gameplay Tag Valid (Tag)
|
||||||
|
├─► True → Return true
|
||||||
|
└─► False → Print Warning: "Invalid Tag: {Get Tag Name(Tag)}" → Return false
|
||||||
|
```
|
||||||
|
|
||||||
|
**Node Search:** `Is Gameplay Tag Valid`, `Get Tag Name`
|
||||||
|
|
||||||
|
### 9.3 GetTagDisplayName
|
||||||
|
|
||||||
|
```
|
||||||
|
[Function: GetTagDisplayName(Tag)] → Text
|
||||||
|
Step 1: Get Tag Display Name (Tag) → Return
|
||||||
|
```
|
||||||
|
|
||||||
|
**Node Search:** `Get Tag Display Name` (Blueprint pure node, available)
|
||||||
|
|
||||||
|
### 9.4 LogAllTags
|
||||||
|
|
||||||
|
```
|
||||||
|
[Function: LogAllTags] (Blueprint Callable)
|
||||||
|
Step 1: GetAllRegisteredTags() → Store in LocalTags
|
||||||
|
Step 2: ForEachLoop (LocalTags):
|
||||||
|
├─► Get Tag Name → ToString → Print String
|
||||||
|
Step 3: Print String: "Total tags: {Array Length(LocalTags)}"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.5 ExportTagNamespace(Prefix: String) → String
|
||||||
|
|
||||||
|
```
|
||||||
|
[Function: ExportTagNamespace]
|
||||||
|
Step 1: GetAllRegisteredTags() → LocalTags
|
||||||
|
Step 2: Create empty String → Output
|
||||||
|
Step 3: ForEachLoop (LocalTags):
|
||||||
|
├─► Get Tag Name → ToString → TagString
|
||||||
|
├─► Branch: Does TagString start with Prefix?
|
||||||
|
│ True → Append TagString + "\n" to Output
|
||||||
|
└─► Continue
|
||||||
|
Step 4: Return Output
|
||||||
```
|
```
|
||||||
[OnAssetLoaded]
|
[OnAssetLoaded]
|
||||||
└─► Call GetAllRegisteredTags()
|
└─► Call GetAllRegisteredTags()
|
||||||
@@ -179,7 +244,20 @@ This asset does not talk to other systems directly. All communication is passive
|
|||||||
|
|
||||||
## 14. Manual Implementation Guide
|
## 14. Manual Implementation Guide
|
||||||
|
|
||||||
> **For human implementer:** Follow these steps to build `DA_GameTagRegistry` in UE5.
|
> **For human implementer:** Follow these steps to build `DA_GameTagRegistry` in UE5 Blueprints.
|
||||||
|
> **⚠️ UE5 BP Limitation:** `UGameplayTagsManager::RequestAllGameplayTags()` is C++ only. This implementation uses a **Data Table proxy** (`DT_ProjectTags`) as the 100% Blueprint workaround. You must create and maintain `DT_ProjectTags` alongside your `DefaultGameplayTags.ini`.
|
||||||
|
|
||||||
|
### 14.0 Prerequisite: Create the Tag Data Table
|
||||||
|
|
||||||
|
Before implementing the Data Asset, create the proxy Data Table:
|
||||||
|
|
||||||
|
1. Right-click in Content Browser → **Miscellaneous → Data Table**
|
||||||
|
2. Row Structure: `GameplayTagTableRow`
|
||||||
|
3. Name: `DT_ProjectTags`
|
||||||
|
4. Save to: `Content/Framework/Core/`
|
||||||
|
5. Add rows: one per tag (row name = anything, fill the "Tag" field with your GameplayTag)
|
||||||
|
6. Go to **Project Settings → GameplayTags → Gameplay Tag Table List** → click `+` → select `DT_ProjectTags`
|
||||||
|
- This auto-registers these tags with the engine's tag manager.
|
||||||
|
|
||||||
### 14.1 Class Setup
|
### 14.1 Class Setup
|
||||||
|
|
||||||
@@ -191,92 +269,126 @@ This asset does not talk to other systems directly. All communication is passive
|
|||||||
### 14.2 Variables
|
### 14.2 Variables
|
||||||
|
|
||||||
Add to Class Defaults:
|
Add to Class Defaults:
|
||||||
| Variable | Type | Instance Editable | Default |
|
| Variable | Type | Instance Editable | Default | Category |
|
||||||
|----------|------|------------------|---------|
|
|----------|------|------------------|---------|----------|
|
||||||
| `TagNamespace` | `Text` | ✓ | *Framework tag namespace description* |
|
| `TagNamespace` | `Text` | ✓ | *"Framework tag namespace documentation"* | Documentation |
|
||||||
| `bIsFrameworkTag` | `Boolean` | ✓ | `true` |
|
| `bIsFrameworkTag` | `Boolean` | ✓ | `true` | Documentation |
|
||||||
|
| `TagDataTable` | `Data Table` (Object Reference) | ✓ | `DT_ProjectTags` | Config |
|
||||||
There are NO tag entries stored in this asset. Tags live in `Project Settings → GameplayTags` or `DefaultGameplayTags.ini`.
|
|
||||||
|
|
||||||
### 14.3 Function Implementations
|
### 14.3 Function Implementations
|
||||||
|
|
||||||
#### `GetAllRegisteredTags` → `Array of GameplayTag`
|
#### `GetAllRegisteredTags()` → `Array<GameplayTag>` *(Blueprint Pure)*
|
||||||
|
|
||||||
**Purpose:** Returns every tag registered in the project.
|
**Purpose:** Returns all tags from the Data Table proxy. This replaces the C++-only `UGameplayTagsManager::RequestAllGameplayTags()`.
|
||||||
|
|
||||||
**Nodes to Use (Blueprint Implementable Function):**
|
**Node-by-Node Logic:**
|
||||||
```
|
```
|
||||||
[Function: GetAllRegisteredTags]
|
[Function: GetAllRegisteredTags] (Pure, no execution pins)
|
||||||
└─ Get All Gameplay Tags (from GameplayTags subsystem)
|
Step 1: Get Data Table Row Names (TagDataTable) → returns Array<Name>
|
||||||
└─ Return the array
|
Step 2: Create empty Array<GameplayTag> → LocalTags
|
||||||
|
Step 3: ForEachLoop over RowNames:
|
||||||
|
├─► Get Data Table Row (TagDataTable, Array Element)
|
||||||
|
│ → Struct Pin: Break GameplayTagTableRow
|
||||||
|
│ → Get "Tag" field (type: GameplayTag)
|
||||||
|
├─► Add "Tag" to LocalTags array
|
||||||
|
Step 4: Return LocalTags
|
||||||
```
|
```
|
||||||
|
|
||||||
**Node Search:** Right-click → "Get All Gameplay Tags"
|
**Nodes to Search:** `Get Data Table Row Names`, `ForEachLoop`, `Get Data Table Row`, `Break GameplayTagTableRow`, `Add`, `Array`
|
||||||
|
|
||||||
#### `GetTagDisplayName(Tag)` → `Text`
|
**⚠️ Note:** Since this is a **Pure** function, the ForEachLoop must be inside a **Pure function graph** (which supports loops in UE5). If your UE version doesn't support loops in Pure functions, make this a **BlueprintCallable** (impure) function instead.
|
||||||
|
|
||||||
**Nodes to Use (Blueprint Pure):**
|
#### `GetTagDisplayName(Tag: GameplayTag)` → `Text` *(Blueprint Pure)*
|
||||||
|
|
||||||
|
**Node-by-Node Logic:**
|
||||||
```
|
```
|
||||||
[Function: GetTagDisplayName]
|
[Function: GetTagDisplayName]
|
||||||
Input Tag → Get Tag Display Name (from GameplayTags)
|
Input Tag → Get Tag Display Name (Tag) → Return
|
||||||
└─ Return the text
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Node Search:** Right-click → "Get Tag Display Name"
|
**Node Search:** `Get Tag Display Name` — this IS available in Blueprint (part of GameplayTags plugin).
|
||||||
|
|
||||||
#### `ValidateTag(Tag)` → `Boolean`
|
#### `ValidateTag(Tag: GameplayTag)` → `Boolean` *(Blueprint Pure)*
|
||||||
|
|
||||||
**Nodes to Use (Blueprint Pure / Callable):**
|
**⚠️ UE5 Limitation:** `UGameplayTagsManager::RequestGameplayTag()` is not directly available in BP. Use `Is Gameplay Tag Valid` instead.
|
||||||
|
|
||||||
|
**Node-by-Node Logic:**
|
||||||
```
|
```
|
||||||
[Function: ValidateTag]
|
[Function: ValidateTag]
|
||||||
Input Tag → Is Valid Tag (from GameplayTags)
|
Step 1: Is Gameplay Tag Valid (Tag)
|
||||||
Branch on result:
|
├─► True → Return true
|
||||||
True → Return true
|
└─► False → Print Warning: "Invalid Tag: " + Get Tag Name(Tag) → Return false
|
||||||
False → Print Warning: "Invalid Tag: {Tag}" → Return false
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Node Search:** Right-click → "Is Gameplay Tag Valid"
|
**Node Search:** `Is Gameplay Tag Valid`, `Get Tag Name`
|
||||||
|
|
||||||
#### `LogAllTags` → *(void)*
|
**⚠️ Note:** `Is Gameplay Tag Valid` returns true only if the tag is registered in the engine's tag table (which `DT_ProjectTags` populates via Project Settings). Tags NOT in the table will return false.
|
||||||
|
|
||||||
**Blueprint Callable — Editor Only:**
|
#### `LogAllTags()` → *(void)* *(Blueprint Callable)*
|
||||||
|
|
||||||
|
**Editor Only.** Prints all tags from the Data Table to the output log.
|
||||||
|
|
||||||
|
**Node-by-Node Logic:**
|
||||||
```
|
```
|
||||||
[Function: LogAllTags]
|
[Function: LogAllTags]
|
||||||
├─ Get All Gameplay Tags → ForEachLoop
|
Step 1: Call GetAllRegisteredTags() → LocalTags
|
||||||
│ └─ Print String: Tag.ToString()
|
Step 2: ForEachLoop (LocalTags):
|
||||||
└─ Print String: "Total tags: {Array Length}"
|
├─► Get Tag Name (Array Element) → ToString → Print String
|
||||||
|
Step 3: Print String: "Total tags: " + Array Length(LocalTags)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Node Search:** Right-click → "ForEachLoop", "Print String"
|
**Node Search:** `ForEachLoop`, `Get Tag Name`, `ToString (String)`, `Print String`, `Array Length`
|
||||||
|
|
||||||
#### `ExportTagNamespace(NamespacePrefix)` → `String`
|
#### `ExportTagNamespace(NamespacePrefix: String)` → `String` *(Blueprint Callable)*
|
||||||
|
|
||||||
**Blueprint Callable:**
|
**Node-by-Node Logic:**
|
||||||
```
|
```
|
||||||
[Function: ExportTagNamespace]
|
[Function: ExportTagNamespace]
|
||||||
├─ Get All Gameplay Tags
|
Step 1: Call GetAllRegisteredTags() → LocalTags
|
||||||
├─ ForEachLoop:
|
Step 2: Create String variable → Output = ""
|
||||||
│ └─ Get Tag Name → ToString
|
Step 3: ForEachLoop (LocalTags):
|
||||||
│ └─ Does string start with NamespacePrefix?
|
├─► Get Tag Name (Array Element) → ToString → TagString
|
||||||
│ True → Append to output string with newline
|
├─► Branch: Does TagString start with NamespacePrefix? (use "Starts With" string node)
|
||||||
└─ Return output string
|
│ True → Append TagString + "\n" to Output (use "Append" or "Build String")
|
||||||
|
└─► Continue
|
||||||
|
Step 4: Return Output
|
||||||
```
|
```
|
||||||
|
|
||||||
### 14.4 Networking
|
**Node Search:** `Starts With (String)`, `Append`, `Build String`, `ForEachLoop`
|
||||||
|
|
||||||
No replication needed. This is a read-only Data Asset. All clients load identical copies from disk.
|
### 14.4 External Initialization
|
||||||
|
|
||||||
### 14.5 Blueprint Build Checklist
|
Since Data Assets have no `BeginPlay`, call validation from your GameInstance or StateManager:
|
||||||
|
|
||||||
- [ ] Create Data Asset: `DA_GameTagRegistry` (Parent: `PrimaryDataAsset`)
|
**In `GI_GameFramework.Init()` or `BPC_StateManager.BeginPlay()`:**
|
||||||
- [ ] Add `TagNamespace` (Text) and `bIsFrameworkTag` (Bool) variables
|
```
|
||||||
- [ ] Implement `GetAllRegisteredTags` function (Pure)
|
Step 1: Get DA_GameTagRegistry (hard reference or Load Asset)
|
||||||
- [ ] Implement `GetTagDisplayName` function (Pure)
|
Step 2: Call DA_GameTagRegistry.GetAllRegisteredTags() → LocalTags
|
||||||
- [ ] Implement `ValidateTag` function (Pure)
|
Step 3: Branch: Array Length(LocalTags) == 0
|
||||||
- [ ] Implement `LogAllTags` (Editor-only)
|
├─► True → Print Warning: "No tags in DT_ProjectTags!"
|
||||||
- [ ] Implement `ExportTagNamespace` (Tooling)
|
└─► False → Print String: "N tags registered: " + Array Length
|
||||||
- [ ] Document all tag namespaces in the asset's Description field (use Section 10 as reference)
|
Step 4: [Debug builds only] Call DA_GameTagRegistry.LogAllTags()
|
||||||
- [ ] Verify: all tag namespaces from Section 10 exist in `DefaultGameplayTags.ini`
|
```
|
||||||
|
|
||||||
|
### 14.5 Networking
|
||||||
|
|
||||||
|
No replication needed. This is a read-only Data Asset with a read-only Data Table reference. All clients load identical copies from disk.
|
||||||
|
|
||||||
|
### 14.6 Blueprint Build Checklist
|
||||||
|
|
||||||
|
- [ ] Create Data Table `DT_ProjectTags` (Row Structure: `GameplayTagTableRow`)
|
||||||
|
- [ ] Populate `DT_ProjectTags` with all framework tags from Section 10
|
||||||
|
- [ ] Add `DT_ProjectTags` to `Project Settings → GameplayTags → Gameplay Tag Table List`
|
||||||
|
- [ ] Create Data Asset `DA_GameTagRegistry` (Parent: `PrimaryDataAsset`)
|
||||||
|
- [ ] Add variables: `TagNamespace` (Text), `bIsFrameworkTag` (Boolean), `TagDataTable` (Data Table Ref → DT_ProjectTags)
|
||||||
|
- [ ] Implement `GetAllRegisteredTags` using Data Table Row iteration
|
||||||
|
- [ ] Implement `GetTagDisplayName` using `Get Tag Display Name` node
|
||||||
|
- [ ] Implement `ValidateTag` using `Is Gameplay Tag Valid` node
|
||||||
|
- [ ] Implement `LogAllTags` (editor-only, prints all tags)
|
||||||
|
- [ ] Implement `ExportTagNamespace` (string prefix filtering)
|
||||||
|
- [ ] Add external initialization call from `GI_GameFramework.Init()` or `BPC_StateManager.BeginPlay()`
|
||||||
|
- [ ] Verify: all tags from Section 10 exist in `DT_ProjectTags`
|
||||||
|
- [ ] Verify: `ValidateTag` returns true for registered tags, false for unregistered
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user