fix(docs): enable raw HTML in markdown with rehype-raw

- Add rehype-raw plugin to allow HTML elements in markdown
- Remove inline script tag from nodes.md (loaded globally in Head.astro)
- This fixes blueprint graph examples not rendering in production
This commit is contained in:
yhh
2026-01-05 19:12:47 +08:00
parent 51334dfc50
commit 6b5b4efa72
4 changed files with 1050 additions and 280 deletions

View File

@@ -3,8 +3,12 @@ import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import vue from '@astrojs/vue';
import tailwindcss from '@tailwindcss/vite';
import rehypeRaw from 'rehype-raw';
export default defineConfig({
markdown: {
rehypePlugins: [rehypeRaw],
},
integrations: [
starlight({
title: 'ESEngine',

View File

@@ -15,6 +15,7 @@
"@astrojs/vue": "^5.1.3",
"@tailwindcss/vite": "^4.1.18",
"astro": "^5.6.1",
"rehype-raw": "^7.0.0",
"sharp": "^0.34.2",
"tailwindcss": "^4.1.18",
"vue": "^3.5.26"

View File

@@ -1,192 +1,609 @@
---
title: "ECS Node Reference"
description: "Blueprint built-in ECS operation nodes"
description: "Blueprint built-in ECS operation nodes - complete reference with visual examples"
---
This document provides a complete reference for all built-in blueprint nodes with visual examples.
<script src="/js/blueprint-graph.js"></script>
## Pin Type Legend
<div class="bp-legend">
<div class="bp-legend-item"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff" stroke="#fff" stroke-width="1"/></svg> Execution Flow</div>
<div class="bp-legend-item"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="transparent" stroke="#00a0e0" stroke-width="2"/></svg> Entity</div>
<div class="bp-legend-item"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="transparent" stroke="#7030c0" stroke-width="2"/></svg> Component</div>
<div class="bp-legend-item"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="transparent" stroke="#7ecd32" stroke-width="2"/></svg> Number</div>
<div class="bp-legend-item"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="transparent" stroke="#e060e0" stroke-width="2"/></svg> String</div>
<div class="bp-legend-item"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="transparent" stroke="#8c0000" stroke-width="2"/></svg> Boolean</div>
</div>
## Event Nodes
Lifecycle events as blueprint entry points:
| Node | Description |
|------|-------------|
| `EventBeginPlay` | Triggered when blueprint starts |
| `EventTick` | Triggered each frame, receives deltaTime |
| `EventEndPlay` | Triggered when blueprint stops |
| Node | Description | Outputs |
|------|-------------|---------|
| `EventBeginPlay` | Triggered when blueprint starts | Exec, Self (Entity) |
| `EventTick` | Triggered each frame | Exec, Delta Time |
| `EventEndPlay` | Triggered when blueprint stops | Exec |
### Example: Game Initialization
<div class="bp-graph" style="" data-connections='[{"from":"en-beginplay-exec","to":"en-print-exec","type":"exec"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 170px;">
<div class="bp-node-header event">
<span class="bp-node-header-icon"></span>
<span class="bp-node-header-title">Event BeginPlay</span>
<span class="bp-header-exec" data-pin="en-beginplay-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Self</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 280px; top: 20px; width: 170px;">
<div class="bp-node-header debug">Print</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-print-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#e060e0" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Message</span>
<span class="bp-pin-value">"Game Started!"</span>
</div>
</div>
</div>
</div>
### Example: Per-Frame Movement
<div class="bp-graph" style="" data-connections='[{"from":"en-tick-exec","to":"en-setprop-exec","type":"exec"},{"from":"en-tick-delta","to":"en-mul-a","type":"float"},{"from":"en-mul-result","to":"en-setprop-x","type":"float"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 140px;">
<div class="bp-node-header event">
<span class="bp-node-header-icon"></span>
<span class="bp-node-header-title">Event Tick</span>
<span class="bp-header-exec" data-pin="en-tick-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-tick-delta"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">Delta Time</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 200px; top: 110px; width: 120px;">
<div class="bp-node-header math">Multiply</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-mul-a"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">A</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">B</span>
<span class="bp-pin-value">100</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-mul-result"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">Result</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 380px; top: 20px; width: 150px;">
<div class="bp-node-header function">Set Property</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-setprop-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7030c0" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Target</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-setprop-x"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">x</span>
</div>
</div>
</div>
</div>
## Entity Nodes
ECS entity operations:
Manipulate ECS entities:
| Node | Description | Type |
|------|-------------|------|
| `Get Self` | Get entity owning this blueprint | Pure |
| `Create Entity` | Create new entity in scene | Execution |
| `Destroy Entity` | Destroy specified entity | Execution |
| `Destroy Self` | Destroy self entity | Execution |
| `Get Self` | Get the entity owning this blueprint | Pure |
| `Create Entity` | Create a new entity in the scene | Exec |
| `Destroy Entity` | Destroy specified entity | Exec |
| `Destroy Self` | Destroy the owning entity | Exec |
| `Is Valid` | Check if entity is valid | Pure |
| `Get Entity Name` | Get entity name | Pure |
| `Set Entity Name` | Set entity name | Execution |
| `Get Entity Tag` | Get entity tag | Pure |
| `Set Entity Tag` | Set entity tag | Execution |
| `Set Active` | Set entity active state | Execution |
| `Is Active` | Check if entity is active | Pure |
| `Set Entity Name` | Set entity name | Exec |
| `Find Entity By Name` | Find entity by name | Pure |
| `Find Entities By Tag` | Find all entities by tag | Pure |
| `Get Entity ID` | Get entity unique ID | Pure |
| `Find Entity By ID` | Find entity by ID | Pure |
| `Find Entities By Tag` | Find all entities with tag | Pure |
### Example: Create Bullet
<div class="bp-graph" style="" data-connections='[{"from":"en-bp-exec","to":"en-create-exec","type":"exec"},{"from":"en-create-exec-out","to":"en-add-exec","type":"exec"},{"from":"en-create-entity","to":"en-add-entity","type":"entity"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 170px;">
<div class="bp-node-header event">
<span class="bp-node-header-icon"></span>
<span class="bp-node-header-title">Event BeginPlay</span>
<span class="bp-header-exec" data-pin="en-bp-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Self</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 280px; top: 20px; width: 150px;">
<div class="bp-node-header function">Create Entity</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-create-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-create-exec-out"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-create-entity"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Entity</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 520px; top: 20px; width: 150px;">
<div class="bp-node-header function">Add Transform</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-add-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-add-entity"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Entity</span>
</div>
</div>
</div>
</div>
## Component Nodes
ECS component operations:
Read and write component properties:
| Node | Description | Type |
|------|-------------|------|
| `Get Component` | Get component of specified type from entity | Pure |
| `Has Component` | Check if entity has specified component | Pure |
| `Get Component` | Get component from entity | Pure |
| `Get All Components` | Get all components from entity | Pure |
| `Remove Component` | Remove component | Execution |
| `Get Component Property` | Get component property value | Pure |
| `Set Component Property` | Set component property value | Execution |
| `Get Component Type` | Get component type name | Pure |
| `Get Owner Entity` | Get owning entity from component | Pure |
| `Add Component` | Add component to entity | Exec |
| `Remove Component` | Remove component from entity | Exec |
| `Get Property` | Get component property value | Pure |
| `Set Property` | Set component property value | Exec |
### Example: Modify Position
<div class="bp-graph" style="" data-connections='[{"from":"en-self-entity","to":"en-getcomp-entity","type":"entity"},{"from":"en-getcomp-transform","to":"en-getprop-target","type":"component"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 100px;">
<div class="bp-node-header pure">Get Self</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-self-entity"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Entity</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 200px; top: 20px; width: 150px;">
<div class="bp-node-header pure">Get Component</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-getcomp-entity"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Entity</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-getcomp-transform"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7030c0"/></svg></span>
<span class="bp-pin-label">Transform</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 430px; top: 20px; width: 120px;">
<div class="bp-node-header pure">Get Property</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-getprop-target"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7030c0"/></svg></span>
<span class="bp-pin-label">Target</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">x</span>
</div>
</div>
</div>
</div>
## Flow Control Nodes
Control execution flow:
Control blueprint execution flow:
| Node | Description |
|------|-------------|
| `Branch` | Conditional branch (if/else) |
| `Sequence` | Execute multiple outputs in sequence |
| `For Loop` | Loop execution |
| `For Each` | Iterate array |
| `While Loop` | Conditional loop |
| `Branch` | Conditional branching (if/else) |
| `Sequence` | Execute multiple branches in order |
| `For Loop` | Loop specified number of times |
| `For Each` | Iterate over array elements |
| `While Loop` | Loop while condition is true |
| `Do Once` | Execute only once |
| `Flip Flop` | Alternate between two branches |
| `Gate` | Toggleable execution gate |
| `Flip Flop` | Alternate between A and B |
| `Gate` | Gate switch control |
### Example: Conditional Branch
<div class="bp-graph" style="" data-connections='[{"from":"en-cond-exec","to":"en-branch-exec","type":"exec"},{"from":"en-cond-result","to":"en-branch-cond","type":"bool"},{"from":"en-branch-true","to":"en-print1-exec","type":"exec"},{"from":"en-branch-false","to":"en-print2-exec","type":"exec"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 60px; width: 120px;">
<div class="bp-node-header pure">Condition</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-cond-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-cond-result"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#8c0000"/></svg></span>
<span class="bp-pin-label">Result</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 220px; top: 60px; width: 110px;">
<div class="bp-node-header flow">Branch</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-branch-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-branch-cond"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#8c0000"/></svg></span>
<span class="bp-pin-label">Cond</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-branch-true"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">True</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-branch-false"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">False</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 420px; top: 20px; width: 120px;">
<div class="bp-node-header debug">Print</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-print1-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#e060e0" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Msg</span>
<span class="bp-pin-value">"Yes"</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 420px; top: 130px; width: 120px;">
<div class="bp-node-header debug">Print</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-print2-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#e060e0" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Msg</span>
<span class="bp-pin-value">"No"</span>
</div>
</div>
</div>
</div>
### Example: For Loop
<div class="bp-graph" style="" data-connections='[{"from":"en-forloop-bp-exec","to":"en-forloop-exec","type":"exec"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 170px;">
<div class="bp-node-header event">
<span class="bp-node-header-icon"></span>
<span class="bp-node-header-title">Event BeginPlay</span>
<span class="bp-header-exec" data-pin="en-forloop-bp-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
</div>
</div>
<div class="bp-node" style="left: 280px; top: 20px; width: 150px;">
<div class="bp-node-header flow">For Loop</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-forloop-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#1cc4c4" stroke-width="2"/></svg></span>
<span class="bp-pin-label">First</span>
<span class="bp-pin-value">0</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#1cc4c4" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Last</span>
<span class="bp-pin-value">10</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Body</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#1cc4c4"/></svg></span>
<span class="bp-pin-label">Index</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Done</span>
</div>
</div>
</div>
</div>
## Time Nodes
| Node | Description | Type |
|------|-------------|------|
| `Delay` | Delay execution | Execution |
| `Get Delta Time` | Get frame delta time | Pure |
| `Get Time` | Get total runtime | Pure |
| Node | Description | Output |
|------|-------------|--------|
| `Delay` | Delay execution by specified seconds | Exec |
| `Get Delta Time` | Get frame delta time | Float |
| `Get Time` | Get total runtime | Float |
### Example: Delayed Execution
<div class="bp-graph" style="" data-connections='[{"from":"en-delay-bp-exec","to":"en-delay-exec","type":"exec"},{"from":"en-delay-done","to":"en-delay-print-exec","type":"exec"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 170px;">
<div class="bp-node-header event">
<span class="bp-node-header-icon"></span>
<span class="bp-node-header-title">Event BeginPlay</span>
<span class="bp-header-exec" data-pin="en-delay-bp-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
</div>
</div>
<div class="bp-node" style="left: 280px; top: 20px; width: 120px;">
<div class="bp-node-header time">Delay</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-delay-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Duration</span>
<span class="bp-pin-value">2.0</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-delay-done"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Done</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 490px; top: 20px; width: 130px;">
<div class="bp-node-header debug">Print</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-delay-print-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#e060e0" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Msg</span>
<span class="bp-pin-value">"After 2s"</span>
</div>
</div>
</div>
</div>
## Math Nodes
Basic Operations:
### Basic Operations
| Node | Description | Inputs | Output |
|------|-------------|--------|--------|
| `Add` | Addition | A, B | A + B |
| `Subtract` | Subtraction | A, B | A - B |
| `Multiply` | Multiplication | A, B | A × B |
| `Divide` | Division | A, B | A / B |
| `Modulo` | Modulo | A, B | A % B |
### Math Functions
| Node | Description | Inputs | Output |
|------|-------------|--------|--------|
| `Abs` | Absolute value | Value | \|Value\| |
| `Sqrt` | Square root | Value | √Value |
| `Pow` | Power | Base, Exp | Base^Exp |
| `Floor` | Floor | Value | ⌊Value⌋ |
| `Ceil` | Ceiling | Value | ⌈Value⌉ |
| `Round` | Round | Value | round(Value) |
| `Clamp` | Clamp to range | Value, Min, Max | min(max(V, Min), Max) |
| `Lerp` | Linear interpolation | A, B, Alpha | A + (B-A) × Alpha |
| `Min` | Minimum | A, B | min(A, B) |
| `Max` | Maximum | A, B | max(A, B) |
### Trigonometric Functions
| Node | Description |
|------|-------------|
| `Add` / `Subtract` / `Multiply` / `Divide` | Basic arithmetic |
| `Modulo` | Modulo operation (%) |
| `Negate` | Negate value |
| `Abs` | Absolute value |
| `Sign` | Sign (+1, 0, -1) |
| `Min` / `Max` | Minimum/Maximum |
| `Clamp` | Clamp to range |
| `Wrap` | Wrap value to range |
Power & Roots:
| Node | Description |
|------|-------------|
| `Power` | Power (A^B) |
| `Sqrt` | Square root |
Rounding:
| Node | Description |
|------|-------------|
| `Floor` | Round down |
| `Ceil` | Round up |
| `Round` | Round to nearest |
Trigonometry:
| Node | Description |
|------|-------------|
| `Sin` / `Cos` / `Tan` | Sine/Cosine/Tangent |
| `Asin` / `Acos` / `Atan` | Inverse trig functions |
| `Sin` | Sine |
| `Cos` | Cosine |
| `Tan` | Tangent |
| `Asin` | Arc sine |
| `Acos` | Arc cosine |
| `Atan` | Arc tangent |
| `Atan2` | Two-argument arc tangent |
| `DegToRad` / `RadToDeg` | Degree/Radian conversion |
Interpolation:
### Random Numbers
| Node | Description |
|------|-------------|
| `Lerp` | Linear interpolation |
| `InverseLerp` | Inverse linear interpolation |
| Node | Description | Inputs | Output |
|------|-------------|--------|--------|
| `Random` | Random float [0, 1) | - | Float |
| `Random Range` | Random in range | Min, Max | Float |
| `Random Int` | Random integer | Min, Max | Int |
Random:
### Comparison Nodes
| Node | Description |
|------|-------------|
| `Random Range` | Random float in range |
| `Random Int` | Random integer in range |
| Node | Description | Output |
|------|-------------|--------|
| `Equal` | A == B | Boolean |
| `Not Equal` | A != B | Boolean |
| `Greater` | A > B | Boolean |
| `Greater Or Equal` | A >= B | Boolean |
| `Less` | A < B | Boolean |
| `Less Or Equal` | A <= B | Boolean |
## Logic Nodes
### Example: Clamp Value
Comparison:
<div class="bp-graph" style="" data-connections='[{"from":"en-rand-result","to":"en-clamp-value","type":"float"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 130px;">
<div class="bp-node-header math">Random Range</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Min</span>
<span class="bp-pin-value">0</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Max</span>
<span class="bp-pin-value">100</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-rand-result"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">Result</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 240px; top: 20px; width: 130px;">
<div class="bp-node-header math">Clamp</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-clamp-value"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">Value</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Min</span>
<span class="bp-pin-value">20</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Max</span>
<span class="bp-pin-value">80</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">Result</span>
</div>
</div>
</div>
</div>
| Node | Description |
|------|-------------|
| `Equal` | Equal (==) |
| `Not Equal` | Not equal (!=) |
| `Greater Than` | Greater than (>) |
| `Greater Or Equal` | Greater than or equal (>=) |
| `Less Than` | Less than (<) |
| `Less Or Equal` | Less than or equal (<=) |
| `In Range` | Check if value is in range |
## Variable Nodes
Logical Operations:
Blueprint-defined variables automatically generate Get and Set nodes:
| Node | Description |
|------|-------------|
| `AND` | Logical AND |
| `OR` | Logical OR |
| `NOT` | Logical NOT |
| `XOR` | Exclusive OR |
| `NAND` | NOT AND |
| Node | Description | Type |
|------|-------------|------|
| `Get <varname>` | Read variable value | Pure |
| `Set <varname>` | Set variable value | Exec |
Utility:
### Example: Counter
| Node | Description |
|------|-------------|
| `Is Null` | Check if value is null |
| `Select` | Choose A or B based on condition (ternary) |
<div class="bp-graph" style="" data-connections='[{"from":"en-cnt-tick-exec","to":"en-cnt-add-exec","type":"exec"},{"from":"en-cnt-get-value","to":"en-cnt-add-a","type":"int"},{"from":"en-cnt-add-result","to":"en-cnt-set-value","type":"int"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 140px;">
<div class="bp-node-header event">
<span class="bp-node-header-icon"></span>
<span class="bp-node-header-title">Event Tick</span>
<span class="bp-header-exec" data-pin="en-cnt-tick-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">Delta</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 20px; top: 120px; width: 110px;">
<div class="bp-node-header variable">Get Count</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-cnt-get-value"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#1cc4c4"/></svg></span>
<span class="bp-pin-label">Value</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 240px; top: 20px; width: 110px;">
<div class="bp-node-header math">Add</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-cnt-add-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-cnt-add-a"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#1cc4c4"/></svg></span>
<span class="bp-pin-label">A</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#1cc4c4" stroke-width="2"/></svg></span>
<span class="bp-pin-label">B</span>
<span class="bp-pin-value">1</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="en-cnt-add-result"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#1cc4c4"/></svg></span>
<span class="bp-pin-label">Result</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 430px; top: 20px; width: 110px;">
<div class="bp-node-header variable">Set Count</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="en-cnt-set-value"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#1cc4c4"/></svg></span>
<span class="bp-pin-label">Value</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
</div>
</div>
</div>
## Debug Nodes
| Node | Description |
|------|-------------|
| `Print` | Print to console |
| `Print` | Output message to console |
## Auto-generated Component Nodes
## Related Documentation
Components marked with `@BlueprintExpose` decorator auto-generate nodes:
```typescript
@ECSComponent('Transform')
@BlueprintExpose({ displayName: 'Transform', category: 'core' })
export class TransformComponent extends Component {
@BlueprintProperty({ displayName: 'X Position' })
x: number = 0;
@BlueprintProperty({ displayName: 'Y Position' })
y: number = 0;
@BlueprintMethod({ displayName: 'Translate' })
translate(dx: number, dy: number): void {
this.x += dx;
this.y += dy;
}
}
```
Generated nodes:
- **Get Transform** - Get Transform component
- **Get X Position** / **Set X Position** - Access x property
- **Get Y Position** / **Set Y Position** - Access y property
- **Translate** - Call translate method
- [Blueprint Editor Guide](./editor-guide) - Learn how to use the editor
- [Custom Nodes](./custom-nodes) - Create custom nodes
- [Blueprint VM](./vm) - Runtime API

View File

@@ -1,17 +1,117 @@
---
title: "ECS 节点参考"
description: "蓝图内置 ECS 操作节点"
description: "蓝图内置 ECS 操作节点完整参考"
---
本文档提供蓝图系统所有内置节点的完整参考,包含可视化示例。
## 引脚类型说明
<div class="bp-legend">
<div class="bp-legend-item"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff" stroke="#fff" stroke-width="1"/></svg> 执行流 (Exec)</div>
<div class="bp-legend-item"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="transparent" stroke="#00a0e0" stroke-width="2"/></svg> 实体 (Entity)</div>
<div class="bp-legend-item"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="transparent" stroke="#7030c0" stroke-width="2"/></svg> 组件 (Component)</div>
<div class="bp-legend-item"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="transparent" stroke="#7ecd32" stroke-width="2"/></svg> 数值 (Float)</div>
<div class="bp-legend-item"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="transparent" stroke="#e060e0" stroke-width="2"/></svg> 字符串 (String)</div>
<div class="bp-legend-item"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="transparent" stroke="#8c0000" stroke-width="2"/></svg> 布尔 (Boolean)</div>
</div>
## 事件节点
生命周期事件,作为蓝图执行的入口点:
| 节点 | 说明 |
|------|------|
| `EventBeginPlay` | 蓝图启动时触发 |
| `EventTick` | 每帧触发,接收 deltaTime |
| `EventEndPlay` | 蓝图停止时触发 |
| 节点 | 说明 | 输出 |
|------|------|------|
| `EventBeginPlay` | 蓝图启动时触发 | Exec, Self (Entity) |
| `EventTick` | 每帧触发 | Exec, Delta Time |
| `EventEndPlay` | 蓝图停止时触发 | Exec |
### 示例:游戏初始化
<div class="bp-graph" style="" data-connections='[{"from":"beginplay-exec","to":"print-exec","type":"exec"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 170px;">
<div class="bp-node-header event">
<span class="bp-node-header-icon"></span>
<span class="bp-node-header-title">Event BeginPlay</span>
<span class="bp-header-exec" data-pin="beginplay-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Self</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 280px; top: 20px; width: 170px;">
<div class="bp-node-header debug">Print</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="print-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#e060e0" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Message</span>
<span class="bp-pin-value">"游戏开始!"</span>
</div>
</div>
</div>
</div>
### 示例:每帧移动
<div class="bp-graph" style="" data-connections='[{"from":"tick-exec","to":"setprop-exec","type":"exec"},{"from":"tick-delta","to":"mul-a","type":"float"},{"from":"mul-result","to":"setprop-x","type":"float"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 140px;">
<div class="bp-node-header event">
<span class="bp-node-header-icon"></span>
<span class="bp-node-header-title">Event Tick</span>
<span class="bp-header-exec" data-pin="tick-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="tick-delta"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">Delta Time</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 200px; top: 110px; width: 120px;">
<div class="bp-node-header math">Multiply</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="mul-a"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">A</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">B</span>
<span class="bp-pin-value">100</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="mul-result"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">Result</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 380px; top: 20px; width: 150px;">
<div class="bp-node-header function">Set Property</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="setprop-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7030c0" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Target</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="setprop-x"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">x</span>
</div>
</div>
</div>
</div>
## 实体节点 (Entity)
@@ -26,167 +126,415 @@ description: "蓝图内置 ECS 操作节点"
| `Is Valid` | 检查实体是否有效 | 纯节点 |
| `Get Entity Name` | 获取实体名称 | 纯节点 |
| `Set Entity Name` | 设置实体名称 | 执行节点 |
| `Get Entity Tag` | 获取实体标签 | 纯节点 |
| `Set Entity Tag` | 设置实体标签 | 执行节点 |
| `Set Active` | 设置实体激活状态 | 执行节点 |
| `Is Active` | 检查实体是否激活 | 纯节点 |
| `Find Entity By Name` | 按名称查找实体 | 纯节点 |
| `Find Entities By Tag` | 按标签查找所有实体 | 纯节点 |
| `Get Entity ID` | 获取实体唯一 ID | 纯节点 |
| `Find Entity By ID` | 按 ID 查找实体 | 纯节点 |
### 示例:创建子弹
<div class="bp-graph" style="" data-connections='[{"from":"bp-exec","to":"create-exec","type":"exec"},{"from":"create-exec-out","to":"add-exec","type":"exec"},{"from":"create-entity","to":"add-entity","type":"entity"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 170px;">
<div class="bp-node-header event">
<span class="bp-node-header-icon"></span>
<span class="bp-node-header-title">Event BeginPlay</span>
<span class="bp-header-exec" data-pin="bp-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Self</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 280px; top: 20px; width: 150px;">
<div class="bp-node-header function">Create Entity</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="create-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="create-exec-out"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="create-entity"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Entity</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 520px; top: 20px; width: 150px;">
<div class="bp-node-header function">Add Transform</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="add-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="add-entity"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Entity</span>
</div>
</div>
</div>
</div>
## 组件节点 (Component)
操作 ECS 组件
读写组件属性
| 节点 | 说明 | 类型 |
|------|------|------|
| `Has Component` | 检查实体是否有指定组件 | 纯节点 |
| `Get Component` | 获取实体的组件 | 纯节点 |
| `Get All Components` | 获取实体所有组件 | 节点 |
| `Remove Component` | 移除组件 | 执行节点 |
| `Get Component Property` | 获取组件属性值 | 纯节点 |
| `Set Component Property` | 设置组件属性值 | 执行节点 |
| `Get Component Type` | 获取组件类型名称 | 纯节点 |
| `Get Owner Entity` | 从组件获取所属实体 | 纯节点 |
| `Get Component` | 从实体获取指定类型组件 | 纯节点 |
| `Has Component` | 检查实体是否拥有指定组件 | 纯节点 |
| `Add Component` | 为实体添加组件 | 执行节点 |
| `Remove Component` | 从实体移除组件 | 执行节点 |
| `Get Property` | 获取组件属性值 | 纯节点 |
| `Set Property` | 设置组件属性值 | 执行节点 |
## 流程控制节点 (Flow)
### 示例:修改位置
控制执行流程:
<div class="bp-graph" style="" data-connections='[{"from":"self-entity","to":"getcomp-entity","type":"entity"},{"from":"getcomp-transform","to":"getprop-target","type":"component"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 100px;">
<div class="bp-node-header pure">Get Self</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="self-entity"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Entity</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 200px; top: 20px; width: 150px;">
<div class="bp-node-header pure">Get Component</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="getcomp-entity"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#00a0e0"/></svg></span>
<span class="bp-pin-label">Entity</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="getcomp-transform"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7030c0"/></svg></span>
<span class="bp-pin-label">Transform</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 430px; top: 20px; width: 120px;">
<div class="bp-node-header pure">Get Property</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="getprop-target"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7030c0"/></svg></span>
<span class="bp-pin-label">Target</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">x</span>
</div>
</div>
</div>
</div>
## 流程控制节点
控制蓝图执行流程:
| 节点 | 说明 |
|------|------|
| `Branch` | 条件分支 (if/else) |
| `Sequence` | 顺序执行多个输出 |
| `For Loop` | 循环执行 |
| `For Each` | 遍历数组 |
| `Branch` | 条件分支if/else |
| `Sequence` | 顺序执行多个分支 |
| `For Loop` | 指定次数循环 |
| `For Each` | 遍历数组元素 |
| `While Loop` | 条件循环 |
| `Do Once` | 执行一次 |
| `Flip Flop` | 交替执行两个分支 |
| `Gate` | 可开关的执行门 |
| `Do Once` | 执行一次 |
| `Flip Flop` | 交替执行 A/B |
| `Gate` | 门控开关 |
## 时间节点 (Time)
### 示例:条件分支
<div class="bp-graph" style="" data-connections='[{"from":"cond-exec","to":"branch-exec","type":"exec"},{"from":"cond-result","to":"branch-cond","type":"bool"},{"from":"branch-true","to":"print1-exec","type":"exec"},{"from":"branch-false","to":"print2-exec","type":"exec"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 60px; width: 120px;">
<div class="bp-node-header pure">Condition</div>
<div class="bp-node-body">
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="cond-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="cond-result"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#8c0000"/></svg></span>
<span class="bp-pin-label">Result</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 220px; top: 60px; width: 110px;">
<div class="bp-node-header flow">Branch</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="branch-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="branch-cond"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#8c0000"/></svg></span>
<span class="bp-pin-label">Cond</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="branch-true"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">True</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="branch-false"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">False</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 420px; top: 20px; width: 120px;">
<div class="bp-node-header debug">Print</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="print1-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#e060e0" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Msg</span>
<span class="bp-pin-value">"是"</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 420px; top: 130px; width: 120px;">
<div class="bp-node-header debug">Print</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="print2-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#e060e0" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Msg</span>
<span class="bp-pin-value">"否"</span>
</div>
</div>
</div>
</div>
### 示例For 循环
<div class="bp-graph" style="" data-connections='[{"from":"forloop-bp-exec","to":"forloop-exec","type":"exec"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 170px;">
<div class="bp-node-header event">
<span class="bp-node-header-icon"></span>
<span class="bp-node-header-title">Event BeginPlay</span>
<span class="bp-header-exec" data-pin="forloop-bp-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
</div>
</div>
<div class="bp-node" style="left: 280px; top: 20px; width: 150px;">
<div class="bp-node-header flow">For Loop</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="forloop-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#1cc4c4" stroke-width="2"/></svg></span>
<span class="bp-pin-label">First</span>
<span class="bp-pin-value">0</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#1cc4c4" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Last</span>
<span class="bp-pin-value">10</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Body</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#1cc4c4"/></svg></span>
<span class="bp-pin-label">Index</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Done</span>
</div>
</div>
</div>
</div>
## 时间节点
| 节点 | 说明 | 输出 |
|------|------|------|
| `Delay` | 延迟执行指定秒数 | Exec |
| `Get Delta Time` | 获取帧间隔时间 | Float |
| `Get Time` | 获取运行总时间 | Float |
### 示例:延迟执行
<div class="bp-graph" style="" data-connections='[{"from":"delay-bp-exec","to":"delay-exec","type":"exec"},{"from":"delay-done","to":"delay-print-exec","type":"exec"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 170px;">
<div class="bp-node-header event">
<span class="bp-node-header-icon"></span>
<span class="bp-node-header-title">Event BeginPlay</span>
<span class="bp-header-exec" data-pin="delay-bp-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
</div>
</div>
<div class="bp-node" style="left: 280px; top: 20px; width: 120px;">
<div class="bp-node-header time">Delay</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="delay-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Duration</span>
<span class="bp-pin-value">2.0</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="delay-done"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Done</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 490px; top: 20px; width: 130px;">
<div class="bp-node-header debug">Print</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="delay-print-exec"><svg width="12" height="12"><polygon points="1,1 11,6 1,11" fill="#fff"/></svg></span>
<span class="bp-pin-label">Exec</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#e060e0" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Msg</span>
<span class="bp-pin-value">"2秒后"</span>
</div>
</div>
</div>
</div>
## 数学节点
### 基础运算
| 节点 | 说明 | 输入 | 输出 |
|------|------|------|------|
| `Add` | 加法 | A, B | A + B |
| `Subtract` | 减法 | A, B | A - B |
| `Multiply` | 乘法 | A, B | A × B |
| `Divide` | 除法 | A, B | A / B |
| `Modulo` | 取模 | A, B | A % B |
### 数学函数
| 节点 | 说明 | 输入 | 输出 |
|------|------|------|------|
| `Abs` | 绝对值 | Value | \|Value\| |
| `Sqrt` | 平方根 | Value | √Value |
| `Pow` | 幂运算 | Base, Exp | Base^Exp |
| `Floor` | 向下取整 | Value | ⌊Value⌋ |
| `Ceil` | 向上取整 | Value | ⌈Value⌉ |
| `Round` | 四舍五入 | Value | round(Value) |
| `Clamp` | 区间钳制 | Value, Min, Max | min(max(V, Min), Max) |
| `Lerp` | 线性插值 | A, B, Alpha | A + (B-A) × Alpha |
| `Min` | 取最小值 | A, B | min(A, B) |
| `Max` | 取最大值 | A, B | max(A, B) |
### 三角函数
| 节点 | 说明 |
|------|------|
| `Sin` | 正弦 |
| `Cos` | 余弦 |
| `Tan` | 正切 |
| `Asin` | 反正弦 |
| `Acos` | 反余弦 |
| `Atan` | 反正切 |
| `Atan2` | 二参数反正切 |
### 随机数
| 节点 | 说明 | 输入 | 输出 |
|------|------|------|------|
| `Random` | 随机浮点数 [0, 1) | - | Float |
| `Random Range` | 范围内随机数 | Min, Max | Float |
| `Random Int` | 随机整数 | Min, Max | Int |
### 比较节点
| 节点 | 说明 | 输出 |
|------|------|------|
| `Equal` | A == B | Boolean |
| `Not Equal` | A != B | Boolean |
| `Greater` | A > B | Boolean |
| `Greater Or Equal` | A >= B | Boolean |
| `Less` | A < B | Boolean |
| `Less Or Equal` | A <= B | Boolean |
### 示例:钳制数值
<div class="bp-graph" style="" data-connections='[{"from":"rand-result","to":"clamp-value","type":"float"}]'>
<svg class="bp-connections"></svg>
<div class="bp-node" style="left: 20px; top: 20px; width: 130px;">
<div class="bp-node-header math">Random Range</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Min</span>
<span class="bp-pin-value">0</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Max</span>
<span class="bp-pin-value">100</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin" data-pin="rand-result"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">Result</span>
</div>
</div>
</div>
<div class="bp-node" style="left: 240px; top: 20px; width: 130px;">
<div class="bp-node-header math">Clamp</div>
<div class="bp-node-body">
<div class="bp-pin-row input">
<span class="bp-pin" data-pin="clamp-value"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">Value</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Min</span>
<span class="bp-pin-value">20</span>
</div>
<div class="bp-pin-row input">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="none" stroke="#7ecd32" stroke-width="2"/></svg></span>
<span class="bp-pin-label">Max</span>
<span class="bp-pin-value">80</span>
</div>
<div class="bp-pin-row output">
<span class="bp-pin"><svg width="12" height="12"><circle cx="6" cy="6" r="4" fill="#7ecd32"/></svg></span>
<span class="bp-pin-label">Result</span>
</div>
</div>
</div>
</div>
## 变量节点
蓝图定义的变量会自动生成 Get 和 Set 节点:
| 节点 | 说明 | 类型 |
|------|------|------|
| `Delay` | 延迟执行 | 执行节点 |
| `Get Delta Time` | 获取帧间隔时间 | 节点 |
| `Get Time` | 获取运行总时间 | 纯节点 |
| `Get <变量名>` | 读取变量值 | 节点 |
| `Set <变量名>` | 设置变量值 | 执行节点 |
## 数学节点 (Math)
基础运算:
## 调试节点
| 节点 | 说明 |
|------|------|
| `Add` / `Subtract` / `Multiply` / `Divide` | 四则运算 |
| `Modulo` | 取模运算 (%) |
| `Negate` | 取负 |
| `Abs` | 绝对值 |
| `Sign` | 符号 (+1, 0, -1) |
| `Min` / `Max` | 最小/最大值 |
| `Clamp` | 限制在范围内 |
| `Wrap` | 循环限制在范围内 |
| `Print` | 输出消息到控制台 |
幂与根:
## 相关文档
| 节点 | 说明 |
|------|------|
| `Power` | 幂运算 (A^B) |
| `Sqrt` | 平方根 |
取整:
| 节点 | 说明 |
|------|------|
| `Floor` | 向下取整 |
| `Ceil` | 向上取整 |
| `Round` | 四舍五入 |
三角函数:
| 节点 | 说明 |
|------|------|
| `Sin` / `Cos` / `Tan` | 正弦/余弦/正切 |
| `Asin` / `Acos` / `Atan` | 反三角函数 |
| `Atan2` | 两参数反正切 |
| `DegToRad` / `RadToDeg` | 角度与弧度转换 |
插值:
| 节点 | 说明 |
|------|------|
| `Lerp` | 线性插值 |
| `InverseLerp` | 反向线性插值 |
随机数:
| 节点 | 说明 |
|------|------|
| `Random Range` | 范围内随机浮点数 |
| `Random Int` | 范围内随机整数 |
## 逻辑节点 (Logic)
比较运算:
| 节点 | 说明 |
|------|------|
| `Equal` | 等于 (==) |
| `Not Equal` | 不等于 (!=) |
| `Greater Than` | 大于 (>) |
| `Greater Or Equal` | 大于等于 (>=) |
| `Less Than` | 小于 (<) |
| `Less Or Equal` | 小于等于 (<=) |
| `In Range` | 检查值是否在范围内 |
逻辑运算:
| 节点 | 说明 |
|------|------|
| `AND` | 逻辑与 |
| `OR` | 逻辑或 |
| `NOT` | 逻辑非 |
| `XOR` | 异或 |
| `NAND` | 与非 |
工具节点:
| 节点 | 说明 |
|------|------|
| `Is Null` | 检查值是否为空 |
| `Select` | 根据条件选择 A 或 B (三元运算) |
## 调试节点 (Debug)
| 节点 | 说明 |
|------|------|
| `Print` | 输出到控制台 |
## 自动生成的组件节点
使用 `@BlueprintExpose` 装饰器标记的组件会自动生成节点:
```typescript
@ECSComponent('Transform')
@BlueprintExpose({ displayName: '变换', category: 'core' })
export class TransformComponent extends Component {
@BlueprintProperty({ displayName: 'X 坐标' })
x: number = 0;
@BlueprintProperty({ displayName: 'Y 坐标' })
y: number = 0;
@BlueprintMethod({ displayName: '移动' })
translate(dx: number, dy: number): void {
this.x += dx;
this.y += dy;
}
}
```
生成的节点:
- **Get Transform** - 获取 Transform 组件
- **Get X 坐标** / **Set X 坐标** - 访问 x 属性
- **Get Y 坐标** / **Set Y 坐标** - 访问 y 属性
- **移动** - 调用 translate 方法
- [蓝图编辑器指南](./editor-guide) - 学习如何使用编辑器
- [自定义节点](./custom-nodes) - 创建自定义节点
- [蓝图虚拟机](./vm) - 运行时 API