Image to Three.js Model
img2threejs/img2threejs
Rebuilds the object in a reference image as a procedural, animation-ready Three.js model written entirely in code, using staged sculpting with quality checks.
Create and modify Blueprint assets, variables, functions, components, event dispatchers, and interfaces.
$ npx skills add kevinpbuckley/VibeUE --skill blueprints -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install kevinpbuckley/VibeUE blueprints --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .claude/skills && cp -r skills-src/Content/Skills/blueprints .claude/skills/blueprints && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "blueprints" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/blueprints into .claude/skills/blueprints/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "blueprints", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/blueprintsType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add kevinpbuckley/VibeUE --skill blueprints -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install kevinpbuckley/VibeUE blueprints --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .agents/skills && cp -r skills-src/Content/Skills/blueprints .agents/skills/blueprints && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "blueprints" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/blueprints into .agents/skills/blueprints/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "blueprints", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kevinpbuckley/VibeUE --skill blueprints -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install kevinpbuckley/VibeUE blueprints --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/Content/Skills/blueprints .cursor/skills/blueprints && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "blueprints" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/blueprints into .cursor/skills/blueprints/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "blueprints", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/kevinpbuckley/VibeUE.git --path Content/Skills/blueprints--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add kevinpbuckley/VibeUE --skill blueprints -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install kevinpbuckley/VibeUE blueprints --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/Content/Skills/blueprints .gemini/skills/blueprints && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "blueprints" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/blueprints into .gemini/skills/blueprints/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "blueprints", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install kevinpbuckley/VibeUE blueprintsInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add kevinpbuckley/VibeUE --skill blueprints -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .github/skills && cp -r skills-src/Content/Skills/blueprints .github/skills/blueprints && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "blueprints" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/blueprints into .github/skills/blueprints/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "blueprints", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kevinpbuckley/VibeUE --skill blueprints -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install kevinpbuckley/VibeUE blueprints --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/Content/Skills/blueprints .opencode/skills/blueprints && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "blueprints" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/blueprints into .opencode/skills/blueprints/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "blueprints", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
blueprintsCreate and modify Blueprint assets, variables, functions, components, event dispatchers, and interfaces.
Blueprints is an agent skill from kevinpbuckley/VibeUE. Create and modify Blueprint assets, variables, functions, components, event dispatchers, and interfaces. Use when the user asks to create a Blueprint/BP, add a variable or component to a Blueprint, make an event dispatcher/delegate, implement a Blueprint interface, or inspect a Blueprint's class/components. For node-level graph wiring, also load blueprint-graphs.
Its SKILL.md is about 7.7k tokens, which your agent loads only when the skill is triggered. The skill folder holds 7 other files, including scripts (for example `introspection.md` and `workflows.md`).
It sits in Game Development. The repository describes itself as: Unreal Engine Vibe Coding tool. The licence is MIT.
Read from SKILL.md and the folder at commit dc051be. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 4 files in scripts/, which the agent can run.
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Blueprints loads about 7.7k tokens when it runs. Until then it costs about 94 tokens; SKILL.md has 2,515 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from kevinpbuckley/VibeUE at commit dc051be, republished under its MIT licence (© kevinpbuckley). 2,515 words, ~7,652 tokens.
.claude/skills/blueprints/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.🧠 Brains complement: IF an
unreal-engine-skills-managertool (external MCP) exists in this session, call it with{action: "load", skill: "blueprint-fundamentals"}for UE domain knowledge on this topic — correct APIs, architecture, best practices — and treat it as the rubric for any review / "best practices" question. If no such tool is available (e.g. running under Claude Code or Codex without that MCP), skip this line entirely and proceed with this skill alone — do NOT attempt the call.
For node-level graph editing (adding nodes, connecting pins, wiring logic, timers, layout), load the
blueprint-graphsskill.
add_component are NOT on the CDOadd_component creates a SCS node template, not an instance on the class default object. So the
obvious way to configure it silently does nothing — get_components_by_class on the CDO returns an
empty list and the loop body never runs:
# WRONG - prints [], the mesh is never assigned, and nothing errors
cdo = unreal.get_default_object(bp.generated_class())
for c in cdo.get_components_by_class(unreal.SkeletalMeshComponent):
c.set_editor_property("skeletal_mesh_asset", mesh)
# CORRECT - go through the service, which edits the SCS template
BS.set_component_property(BP, "Windmill", "SkeletalMeshAsset", "/Game/X/SK_Windmill.SK_Windmill")
BS.set_component_property(BP, "Windmill", "AnimationMode", "AnimationBlueprint")
BS.set_component_property(BP, "Windmill", "AnimClass", "/Game/X/ABP_Windmill.ABP_Windmill_C")Values are strings: an asset takes its object path (/Game/X/SK.SK), a class takes the
_C path, an enum takes the entry name. Read back with get_component_property to confirm — it
returns the resolved object, e.g.
/Script/Engine.SkeletalMesh'/Game/X/SK_Windmill.SK_Windmill'. Components that come from the
parent C++ class are on the CDO and can be set directly; only SCS-added ones need the service.
Every unreal.BlueprintService.* function that takes a blueprint_path also accepts a map/world
path (e.g. /Game/Maps/MainMenu) and resolves it to that level's Level Blueprint — inspect and
edit level scripts exactly like normal Blueprints. Explicit subobject paths
(/Game/Maps/MyMap.MyMap:PersistentLevel.MyMap) work too. Compile still goes through
unreal.BlueprintEditorLibrary.compile_blueprint(...) on the returned/loaded level script, and the
MAP asset is what you save afterwards (unreal.EditorAssetLibrary.save_asset("/Game/Maps/MyMap")).
BlueprintTools args are {refPath} objects, NOT stringsEvery UObject/UClass argument to the engine BlueprintTools toolset (blueprint, asset_type,
graph, parent_class, …) is a reference object {"refPath": "<object path>"}, and these tools
return the same shape. Passing a plain string fails with
"<x> is not a valid object path for property '<arg>'". This rule is only for the engine
BlueprintTools call_tool path — VibeUE's own unreal.BlueprintService.* Python methods still take
plain string paths.
The refPath must be the full object path — /Game/Dir/Asset.Asset (the asset name repeated
after the dot). A bare package path (/Game/Dir/Asset, no .Asset) is rejected. Two safe ways
to get one:
# (a) Reuse what create/load returns — it is already a {refPath} object:
bp_ref = call_tool("create", "editor_toolset.toolsets.blueprint.BlueprintTools",
{"folder_path": "/Game/BP", "asset_name": "BP_X",
"asset_type": {"refPath": "/Script/Engine.Actor"}})["returnValue"]
# (b) Build one from a package path you already have:
def bp_ref_of(p): # "/Game/Dir/BP_X" -> {"refPath": "/Game/Dir/BP_X.BP_X"}
name = p.rsplit("/", 1)[-1].split(".")[0]
return {"refPath": p if "." in p.rsplit("/", 1)[-1] else f"{p}.{name}"}All the arguments={"blueprint": path, ...} / {"blueprint": bp, ...} examples in the sub-docs are
shorthand — wrap the path with bp_ref_of(...) (or reuse the returned ref) when you actually call.
On success these tools return {"returnValue": null}; an error comes back as a Parameter error.
BlueprintTools.createBlueprint basics now live on the engine's BlueprintTools toolset (VibeUE extends the native MCP
endpoint). Create a Blueprint with call_tool, not unreal.BlueprintService.create_blueprint (that
method was cut):
# CORRECT — folder_path + asset_name are strings; asset_type is a {refPath} class reference.
result = call_tool(
tool_name="create",
toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools",
arguments={"folder_path": "/Game/Blueprints", "asset_name": "BP_MyActor",
"asset_type": {"refPath": "/Script/Engine.Actor"}},
)
# -> {"returnValue": {"refPath": "/Game/Blueprints/BP_MyActor.BP_MyActor"}}
bp_ref = result["returnValue"] # reuse this {refPath} object for later BlueprintTools callsThe folder and asset name are passed separately (folder_path + asset_name) — do not jam a full
asset path into one argument. asset_type is the parent class as a {refPath}:
/Script/Engine.Actor, /Script/Engine.Pawn, /Script/Engine.Character, or a Blueprint's generated
class "/Game/.../BP_Base.BP_Base_C".
BlueprintTools.add_variableAdding a variable is also an engine BlueprintTools call now (unreal.BlueprintService.add_variable
was cut). Use call_tool with blueprint, name, type_name (and add_object_variable /
add_struct_variable for object- and struct-typed variables):
# CORRECT — blueprint is a {refPath} object; name/type_name are strings
call_tool(
tool_name="add_variable",
toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools",
arguments={"blueprint": {"refPath": "/Game/BP_MyActor.BP_MyActor"}, "name": "Health", "type_name": "float"},
)When the variable's type is a Blueprint class, use the Blueprint asset name directly in
type_name. Do not add _C, and do not construct a generated class path — just use the name
("BP_Enemy", or the full "/Game/Blueprints/BP_Enemy"). Appending _C ("BP_Enemy_C") or guessing
a generated class path is wrong; the type system resolves Blueprint names automatically via asset
search.
Engine structs need the F prefix: color variables are "FLinearColor" / "FColor" —
plain "LinearColor" / "Color" is not resolved. Unsure of a type string? Use the surviving
unreal.BlueprintService.search_variable_types("Linear") to look it up.
Supported primitive type_name values (exact): bool, int, float, byte, name, string,
text, Vector, Rotator, Transform, Vector2D, LinearColor. Use int (not int32) and
float (not double) — add_variable rejects int32/double with
"Unknown type 'int32'. Supported: …". For other engine structs (e.g. FColor, FGameplayTag) use
add_struct_variable with struct_type; for object/class refs use add_object_variable with
object_class as a {refPath}:
# Object-reference variable — object_class is a {refPath} to the class
call_tool("add_object_variable", "editor_toolset.toolsets.blueprint.BlueprintTools",
{"blueprint": {"refPath": "/Game/BP_MyActor.BP_MyActor"}, "name": "DeathFX",
"object_class": {"refPath": "/Script/Niagara.NiagaraSystem"}})add_member_variable (VibeUE delta)From inside execute_python_code, unreal.BlueprintService.add_member_variable(bp_path, name, type_string, default="", is_array=False, container_type="") creates a member variable with full
type-string support — structs, objects, enums, and containers — in one batchable Python call
(no call_tool round-trip). It takes the same type strings as add_function_local_variable
("float", "FVector", "FStateTreeDelegateDispatcher", "AActor"):
unreal.BlueprintService.add_member_variable(bp_path, "FinishRotatingDispatcher", "FStateTreeDelegateDispatcher")
unreal.BlueprintService.add_member_variable(bp_path, "Waypoints", "FVector", "", True) # FVector array
unreal.BlueprintEditorLibrary.compile_blueprint(unreal.EditorAssetLibrary.load_asset(bp_path))Returns False (with the reason in the log) on a duplicate name or an unresolvable type string.
Compile after adding — the variable is registered but the class is only rebuilt on compile.
remove_member_variable (VibeUE delta)unreal.BlueprintService.remove_member_variable(bp_path, name, force=False) removes exactly one
member variable. The engine alternative, BlueprintEditorLibrary.remove_unused_variables, sweeps
every unreferenced variable — use this when you want to delete just one. It counts Get/Set
references across all graphs first: with references present and force=False it refuses (returns
False, logs the referencing graphs and node counts); with force=True it removes the variable
and its referencing nodes. A component name (from the Simple Construction Script) is refused with a
pointer to the component API. Verifies by readback and returns True only when the variable is gone.
unreal.BlueprintService.remove_member_variable(bp_path, "UnusedScratch") # refuses if referenced
unreal.BlueprintService.remove_member_variable(bp_path, "OldHealth", True) # force: nodes go tooBlueprintTools.add_function_graphCreating a function graph moved to the engine toolset (create_function / add_function on
BlueprintService were cut). Use call_tool with blueprint + graph_name:
call_tool(
tool_name="add_function_graph",
toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools",
arguments={"blueprint": {"refPath": "/Game/Blueprints/BP_MyActor.BP_MyActor"}, "graph_name": "DoThing"},
)Refining the graph afterward still uses the surviving VibeUE delta methods
(add_function_parameter, add_function_local_variable, get_function_parameters,
get_function_info, override_function, open_function_graph).
| WRONG | CORRECT |
|---|---|
get_component_info(path, name) | get_component_info(type) - takes ONLY type! |
| WRONG | CORRECT |
|---|---|
info.inputs | info.input_parameters |
var.name | var.variable_name |
b Prefix Is StrippedUE Python strips the lowercase b prefix from boolean properties. Always use the name without it:
| C++ name | Python name |
|---|---|
bAlreadyOverridden | already_overridden |
bIsEventStyle | is_event_style |
bIsNativeEvent | is_native_event |
bEnabled | enabled |
Do not use b_already_overridden, b_is_event_style, etc. — these will raise AttributeError.
Exception: the string-based CDO accessors get_property / set_property take the native C++
property name, so booleans KEEP the b prefix there ("bReplicates", not "replicates"). See the
next section.
get_property / set_property (replication, lifespan, etc.)Use these to read/write Class Default Object properties like replication or initial lifespan:
import unreal
bp = "/Game/Blueprints/TestActor"
# READ — returns a single value: str, or None if the property wasn't found. NOT a (success, value) tuple!
value = unreal.BlueprintService.get_property(bp, "bReplicates") # "True" / "False" (a STRING)
life = unreal.BlueprintService.get_property(bp, "InitialLifeSpan") # "5.000000"
# WRONG — raises ValueError: too many values to unpack
# success, value = unreal.BlueprintService.get_property(bp, "bReplicates")
# WRITE — values are strings; returns bool
unreal.BlueprintService.set_property(bp, "bReplicates", "True")
# Compile via the engine BlueprintTools toolset (compile_blueprint was cut from BlueprintService):
# call_tool(tool_name="compile_blueprint",
# toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools",
# arguments={"blueprint": {"refPath": "/Game/Blueprints/TestActor.TestActor"}})
unreal.EditorAssetLibrary.save_asset(bp)Rules:
bool Func(..., Out&) into one return value. This
applies to every get_*_info method too (get_variable_info, get_function_info,
get_component_info, get_node_details): they return the info struct or None, never a tuple.bReplicates, InitialLifeSpan, bCanBeDamaged —
the b prefix is NOT stripped here (a stripped name returns None).value == "True", not value is True.set_property maps the deprecated GameplayEffect CDO fields
InheritableGameplayEffectTags and InheritableOwnedTagsContainer to their Asset Tags and
Target Tags GameplayEffect Components. Writing only the legacy fields is otherwise erased by
UGameplayEffect::PreSave.get_blueprint_info(path) → BlueprintDetailedInfo: blueprint_name, blueprint_path,
parent_class, is_widget_blueprint, variables, functions, components.
| Struct | Fields |
|---|---|
BlueprintFunctionInfo (from list_functions) | function_name, return_type, parameters, is_override, is_pure — there is no function_type and no input_parameters (that's the Detailed struct) |
BlueprintFunctionDetailedInfo (from get_function_info) | function_name, graph_guid, input_parameters, output_parameters, local_variables, is_override, is_pure, node_count — there is no return_type; return values are entries in output_parameters (each param: parameter_name, parameter_type, is_output, is_reference, default_value) |
BlueprintVariableInfo | variable_name, variable_type, category, is_public, is_exposed, default_value |
BlueprintVariableDetailedInfo (from get_variable_info) | variable_name, variable_type, type_path, category, default_value, tooltip, is_array, is_set, is_map, is_instance_editable, is_blueprint_read_only, is_expose_on_spawn, is_expose_to_cinematics, is_private, replication_condition — booleans use the is_ prefix (instance_editable alone raises AttributeError) |
BlueprintLocalVariableInfo (in BlueprintFunctionDetailedInfo.local_variables) | variable_name, friendly_name, variable_type, display_type, default_value, category, guid, is_const, is_reference, is_array, is_set, is_map — local variables are NOT parameters: there is no parameter_name |
BlueprintPinInfo (from get_node_pins / node.pins) | pin_name, pin_type, is_input, is_connected, default_value — direction is the single is_input bool; there is no is_output (use not pin.is_input) |
BlueprintNodeTypeInfo (from discover_nodes) | display_name, category, spawner_key, node_class, tooltip, is_pure, is_latent, keywords — the description text is tooltip, not description |
BlueprintComponentInfo | component_name, component_class, attach_parent, is_root_component, is_scene_component, is_inherited, children |
BlueprintGraphInfo (from list_graphs) | graph_name, graph_kind, node_count |
BlueprintNodeInfo (from get_nodes_in_graph) | node_id, node_type, node_title, pos_x, pos_y, pin_names, pins |
BlueprintCompileResult | success, num_errors, num_warnings, errors, warnings |
ComponentDetailedInfo (from get_component_info) | name, display_name, class_path, category, parent_class, is_scene_component, is_primitive_component, property_count, function_count — there is no description |
ComponentTypeInfo (from get_available_components) | name, display_name, class_path, category, base_class, is_scene_component, is_primitive_component, is_abstract |
ComponentPropertyInfo (from get_all_component_properties) | property_name, property_type, category, value, is_editable, is_inherited |
unreal.BlueprintService)These signatures are complete — no need to discover_python_class them again:
| Method | Notes |
|---|---|
get_available_components(search_filter="", max_results=50) → [ComponentTypeInfo] | Discover addable component types by partial name match |
get_component_info(component_type) → ComponentDetailedInfo or None | Takes ONLY the type name — no blueprint path |
list_components(bp) / get_component_hierarchy(bp) → [BlueprintComponentInfo] | Both return the same flat list — use attach_parent / children / is_root_component fields to render the tree |
component_exists(bp, name) → bool | Fast idempotency check before adding |
add_component(bp, type, name, parent_name="") → bool | Compiles inline. See root behavior below |
remove_component(bp, name, remove_children=True) → bool | Removes children too by default |
reparent_component(bp, name, new_parent) → bool | |
set_root_component(bp, name) → bool | New root must be a SceneComponent. Old auto-generated DefaultSceneRoot is removed; an old user-created root and any other root-level scene components become children of the new root |
get_component_property(bp, comp, prop) → str or None | |
set_component_property(bp, comp, prop, value) → bool | value is a STRING — see formats below |
get_all_component_properties(bp, comp, include_inherited=True) → [ComponentPropertyInfo] | list_component_properties is an alias |
compare_components(bp_a, comp_a, bp_b, comp_b) → str or None | Diff as text; same or different blueprints |
set_collision_settings(bp, comp, collision_enabled, object_type, collision_profile, channel_responses) → bool | Collision lives in BodyInstance — set_component_property cannot reach it |
Root component behavior: components added with no parent_name go to root level. The first
scene component added this way replaces the auto-generated DefaultSceneRoot and becomes the root;
later parentless scene components become floating siblings, NOT children of the root. To build a
hierarchy, pass parent_name when adding, or use reparent_component / set_root_component.
set_component_property)Values are strings in UE export-text syntax. Check property_type via
get_all_component_properties before guessing a struct format:
| Property type | Format example |
|---|---|
float / int32 / bool | "5000.0", "25", "true" |
FVector / FRotator | "(X=0,Y=0,Z=50)", "(Pitch=0,Yaw=90,Roll=0)" |
FColor (e.g. light LightColor) | "(R=255,G=127,B=0,A=255)" — integer bytes 0–255 |
FLinearColor | "(R=1.0,G=0.5,B=0.0,A=1.0)" — floats 0–1 |
Enum (e.g. IntensityUnits) | "Candelas" |
❌ Common mistake: LightColor is FColor, so passing LinearColor-style floats like
"(R=1,G=0.5,B=0)" silently produces a nearly-black light (R=1 of 255), not orange.
To add a StateTree delegate dispatcher variable to a Blueprint task (e.g. STT_*):
# Use type "FStateTreeDelegateDispatcher" — NOT "EventDispatcher".
# The engine's BlueprintTools.add_variable REJECTS this type ("Unknown type" — basic types
# only, live-verified); use the VibeUE struct-capable door instead:
unreal.BlueprintService.add_member_variable(bp_path, "FinishRotatingDispatcher", "FStateTreeDelegateDispatcher")
unreal.BlueprintEditorLibrary.compile_blueprint(unreal.EditorAssetLibrary.load_asset(bp_path))"EventDispatcher" is a Blueprint-only concept and is not a valid type string. The correct type
for StateTree delegate transitions is the USTRUCT FStateTreeDelegateDispatcher.
After adding this variable, use bind_transition_to_delegate on the StateTree to link it to a
transition — it matches the task by registered class name (STT_Rotate_C), not asset path.
Use the dedicated dispatcher API — NOT add_variable — to create the multicast delegates that appear in the Blueprint editor's Event Dispatchers section:
| Method | What it does |
|---|---|
add_event_dispatcher(bp_path, name) | Adds the dispatcher (member variable + signature graph). Skeleton is recompiled inline; the dispatcher is callable immediately. |
add_event_dispatcher_parameter(bp_path, name, param_name, param_type, is_array=False, container_type="") | Adds a parameter to the dispatcher's signature. Subscribers receive these as inputs. |
add_call_delegate_node(bp_path, graph, name, pos_x, pos_y) | Spawns the "Call <Name>" broadcast node on a UK2Node_CallDelegate. Wire the broadcast into its execute pin. |
remove_event_dispatcher(bp_path, name) | Removes the dispatcher and its signature graph. |
import unreal
bp = "/Game/StateTree/BP_Cube"
# 1. Create the dispatcher (no compile needed before placing nodes — skeleton is regenerated inline)
unreal.BlueprintService.add_event_dispatcher(bp, "FinishedLooking")
# 2. (Optional) Add parameters to the signature
unreal.BlueprintService.add_event_dispatcher_parameter(bp, "FinishedLooking", "Direction", "FRotator")
# 3. Spawn the Call node and wire something into its execute pin
call_id = unreal.BlueprintService.add_call_delegate_node(bp, "EventGraph", "FinishedLooking", 1400, -700)
unreal.BlueprintService.connect_nodes(bp, "EventGraph", timeline_id, "Finished", call_id, "execute")
# 4. Compile (engine BlueprintTools toolset) + save
# call_tool(tool_name="compile_blueprint",
# toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools",
# arguments={"blueprint": bp})
unreal.EditorAssetLibrary.save_asset(bp)Pins on the Call node: execute (input exec), then (output exec), self (input target — defaulted to Self), plus one input pin per signature parameter.
Subscribing to it elsewhere:
add_delegate_bind_on_variable(other_bp, graph, variable_name, "FinishedLooking", x, y) when the dispatcher lives on the class of an existing variable (e.g. Cube : BP_Cube_C). Mirrors add_function_call_on_variable: derives the owner class from the variable's type, creates the bind node + Get, and auto-wires Target. Pair with add_custom_event_node and wire CustomEvent.OutputDelegate → Bind.Delegate.add_delegate_bind_node(other_bp, graph, "<owner class>", "FinishedLooking", x, y) when you have no variable to derive from. <owner class> accepts "Self", native class names (with/without U/A prefix), Blueprint asset paths (/Game/.../BP_Cube), or short BP names with/without _C (BP_Cube, BP_Cube_C). You wire the Target pin yourself.Common mistakes:
add_variable(bp, "FinishedLooking", "EventDispatcher") — "EventDispatcher" is not a real type string; use add_event_dispatcher instead.add_get_variable_node on it produces a delegate-getter, not a broadcast). The broadcast node is UK2Node_CallDelegate and is created only by add_call_delegate_node.BlueprintTools.compile_blueprint toolset call before save_asset to ensure the generated class is up-to-date.Add or remove a Blueprint Interface on a Blueprint class — the equivalent of Class Settings → Interfaces → Add in the editor.
| Method | What it does |
|---|---|
add_interface(bp_path, interface) | Implements the interface on the Blueprint. No-op (returns True) if it is already implemented. Marks the Blueprint structurally modified and recompiles it inline. |
remove_interface(bp_path, interface) | Removes the interface from the Blueprint. Marks structurally modified and recompiles inline. |
import unreal
bp = "/Game/Blueprints/BP_Player"
# Prefer the FULL interface asset path — most reliable resolution
unreal.BlueprintService.add_interface(bp, "/Game/Interfaces/BPI_Interactable")
# Short name also works IF the interface asset is already loaded in the editor
unreal.BlueprintService.add_interface(bp, "BPI_Interactable")
# Persist (both methods compile inline, but still save the asset)
unreal.EditorAssetLibrary.save_asset(bp)
# Remove it later
unreal.BlueprintService.remove_interface(bp, "BPI_Interactable")
unreal.EditorAssetLibrary.save_asset(bp)Notes & gotchas:
/Game/Interfaces/BPI_Interactable). Short-name resolution only finds interface Blueprints that are already loaded in the editor; a full path always loads and resolves.CompileBlueprint) but do not save it — call EditorAssetLibrary.save_asset(bp) afterward to persist.add_interface is idempotent — calling it for an interface that is already implemented returns True without duplicating it.override_function(bp_path, function_name) to implement them in the graph.bool (True on success). A False from add_interface means either the interface path could not be resolved, or it resolved to an asset that is not a Blueprint Interface (e.g. a normal Blueprint or one merely parented to UInterface) — check the log and pass a real Blueprint Interface asset path.BPTYPE_Interface), created with BlueprintInterfaceFactory. add_interface validates this and returns False for non-interface classes rather than letting the compile fail.Authoring the interface itself. A Blueprint Interface is nothing but its function graphs, so an
empty one contributes nothing when implemented. Use create_function_graph() to define it — it is
the counterpart to override_function(), which can only override a function that already exists:
BS = unreal.BlueprintService
BS.create_function_graph(bpi_path, "Interact") # void -> an event on implementers
BS.create_function_graph(bpi_path, "GetDisplayName") # returns the graph name, "" on failure
BS.add_function_parameter(bpi_path, "GetDisplayName", "Name", "string", True) # is_output=True -> a return value
BS.add_interface(bp_path, bpi_path)
BS.override_function(bp_path, "Interact") # void interface fn -> event node in the EventGraphcreate_function_graph() also works on a normal Blueprint (pass is_pure=True for a pure function).
It returns "" and logs the reason for: an empty or non-identifier name, a name already used by any
graph on the Blueprint, or a name that already exists on the parent hierarchy — that last case is
override_function()'s job, and a shadowing graph would be a duplicate-function compile error.
A return-valued interface function is materialised as a graph on the implementer and shows up in
list_graphs() as Interface (<InterfaceClass>).
| Task | Workflow | Sample script (run via execute_python_code) |
|---|---|---|
| Create a Blueprint + variables | workflows.md → Create a Blueprint | scripts/create_blueprint.txt |
| Add components + set properties | workflows.md → Add components | scripts/add_component.txt |
| Add an event dispatcher (delegate) | workflows.md → Event dispatcher | scripts/event_dispatcher.txt |
| Implement a Blueprint interface | workflows.md → Implement an interface | scripts/add_interface.txt |
| Inspect a Blueprint (components, parent class) | introspection.md | — |
| Node-level graph editing | load the blueprint-graphs skill | — |
workflows.md — step-by-step create/component/dispatcher/interface workflows with copy-paste Python.introspection.md — what Blueprint introspection works/doesn't in UE 5.7 (CDO reads, parent class via
asset tags, listing BPs by class, getting level actors).After any edit: compile via the engine BlueprintTools.compile_blueprint toolset call
(call_tool(tool_name="compile_blueprint", toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools", arguments={"blueprint": path}))
and check the result's success / num_errors, then unreal.EditorAssetLibrary.save_asset(path).
Don't claim success until compile reports zero errors.
SubobjectDataSubsystem is an ENGINE subsystem (get_engine_subsystem); get_object_for_blueprint lives on SubobjectDataBlueprintFunctionLibrary; SCS templates are named <Name>_GEN_VARIABLE; a SubobjectDataHandle has no is_valid() — test k2_find_subobject_data_from_handle(h) is not None.set_collision_enabled(NO_COLLISION) on a spawned actor's component does not survive save/reload; set_collision_profile_name("NoCollision") serialises, and can_ever_affect_navigation=False persists.© kevinpbuckley, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 6 other files (scripts) in Content/Skills/blueprints of kevinpbuckley/VibeUE.
Open the folder on GitHubat commit dc051be
Blueprints next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Blueprints this skillkevinpbuckley/VibeUE | 730 | — | ~7.7k | Automated safety check: Pass | MIT | |
| Image to Three.js Modelimg2threejs/img2threejs | 18k | 1 repos | ~8.2k | Automated safety check: Pass | Apache-2.0 | |
| Web CloneJane-xiaoer/claude-skill-web-clone | 1k | 1 repos | ~2.7k | Automated safety check: Pass | MIT | |
| Threejs Game Directormajidmanzarpour/threejs-game-skills | 2.5k | — | ~2.2k | Automated safety check: Pass | MIT | |
| Game Asset Generatorhtdt/godogen | 7.1k | — | ~2.8k | Automated safety check: Pass | MIT | |
| Threejs Gameplay Systemsvalkor-ai/loom | 1.2k | 1 repos | ~1.4k | Automated safety check: Pass | Apache-2.0 |
img2threejs/img2threejs
Rebuilds the object in a reference image as a procedural, animation-ready Three.js model written entirely in code, using staged sculpting with quality checks.
Jane-xiaoer/claude-skill-web-clone
网站复刻 / 克隆方法论。USE WHEN 用户说 复刻网站、克隆网站、clone website、抄个站、仿站、 照着这个站做一个、reproduce site、还原某个网页效果、把这个站搬下来改成我的、 复刻某个交互/WebGL/Canvas/Three.js 效果。提供「先拿真源码 → 判路径 → 逆向拆解 → 搭工程 → 替换内容」的可移植决策树,覆盖静态站 /…
majidmanzarpour/threejs-game-skills
Entrypoint for building, upgrading, and finishing Three.js browser games.
htdt/godogen
Generates game art from text prompts: PNG images, GLB 3D models, rigged characters, animations and sprites, with background removal.
valkor-ai/loom
Build and iterate playable Three.js game systems: starter scaffold, architecture, design briefs, core loops, level and encounter design, entities, input, camera, collision and physics, scoring…
CyberAgentGameEntertainment/NovaShader
Execute C with Unity APIs when existing uloop tools cannot inspect or edit enough.
kevinpbuckley/VibeUE
Previews, validates and bakes bone-rotation edits on Unreal Engine AnimSequences, enforcing a coordinate space and a constraint-checked preview-validate-bake loop.
kevinpbuckley/VibeUE
Creates and edits Unreal Engine Animation Montages through AnimMontageService: sections, slots, segments, branching points, notifies and blend settings.
kevinpbuckley/VibeUE
Creates and edits AnimSequence keyframes and bone tracks in Unreal Engine through AnimSequenceService, following an inspect, preview, validate and bake workflow with correct bone-space handling.
kevinpbuckley/VibeUE
Imports files into Unreal Engine, exports textures, reads the Content Browser selection and checks open assets via VibeUE, plus mesh reimport material fixes.
kevinpbuckley/VibeUE
Changes Unreal Engine console variables, scalability levels and raw INI values through VibeUE's Python API, now that registered settings moved to the engine's own toolset.
kevinpbuckley/VibeUE
Creates and wires Unreal Engine Enhanced Input assets through VibeUE's InputService: Input Actions, Mapping Contexts, key bindings, triggers and modifiers.
Categories
Create and modify Blueprint assets, variables, functions, components, event dispatchers, and interfaces. Blueprints is an agent skill from kevinpbuckley/VibeUE. Create and modify Blueprint assets, variables, functions, components, event dispatchers, and interfaces.
Blueprints fits situations like: the user asks to create a Blueprint/BP; component to a Blueprint; make an event dispatcher/delegate; implement a Blueprint interface.
Run `npx skills add kevinpbuckley/VibeUE --skill blueprints -a claude-code`. Or copy the skill folder (Content/Skills/blueprints in kevinpbuckley/VibeUE) into .claude/skills/blueprints in your project. Claude Code loads it when a task matches its description.
Run `npx skills add kevinpbuckley/VibeUE --skill blueprints -a codex`. Or copy the skill folder (Content/Skills/blueprints in kevinpbuckley/VibeUE) into .agents/skills/blueprints in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add kevinpbuckley/VibeUE --skill blueprints -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/blueprints, .gemini/skills/blueprints, .github/skills/blueprints and .opencode/skills/blueprints in your project.
SKILL.md names no scripts, command-line tools or credentials: Blueprints is instructions for the agent only. Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Blueprints is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 7.7k tokens (SKILL.md is roughly 31k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Blueprints: Image to Three.js Model (img2threejs/img2threejs, 18k stars), Web Clone (Jane-xiaoer/claude-skill-web-clone, 1k stars), Threejs Game Director (majidmanzarpour/threejs-game-skills, 2.5k stars) and Game Asset Generator (htdt/godogen, 7.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
kevinpbuckley (a GitHub user) maintains it in kevinpbuckley/VibeUE, which has 730 GitHub stars. The repository holds 39 skills in this directory. The repository was last updated on October 7, 2026.
Source: kevinpbuckley/VibeUE on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.