Agent skill

Unreal Asset Import and Export

by kevinpbuckley in 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.

MITAuto-check passedGame Development

Install Unreal Asset Import and Export

skills CLI
$ npx skills add kevinpbuckley/VibeUE --skill asset-management -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install kevinpbuckley/VibeUE asset-management --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .claude/skills && cp -r skills-src/Content/Skills/asset-management .claude/skills/asset-management && rm -rf skills-src

Use ~/.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/

Facts

Skill name
asset-management
GitHub stars
730
Token cost
~6.5k tokens
SKILL.md length
2,199 words
Files
4 (incl. scripts, references)
Skills in repo
39
Repo updated
First seen
Licence
MIT

At a glance

Imports files into Unreal Engine, exports textures, reads the Content Browser selection and checks open assets via VibeUE, plus mesh reimport material fixes.

  • Importing an image, mesh or other file from disk into the editor
  • SKILL.md covers Data Assets & Data Tables — no…, Critical Rules, Workflows and Sample scripts (run via…, plus 1 more section
  • Runs Python scripts from its folder
  • Exporting a texture asset to a file

What it does

After Unreal 5.8 consolidated general asset operations, the engine's native AssetTools toolset or EditorAssetLibrary handles searching, loading, saving, moving, renaming, duplicating and deleting assets, so this skill covers only the remaining AssetDiscoveryService calls: import_asset and import_texture for bringing in images, meshes or other importable files, export_texture, get_primary_content_browser_selection and is_asset_open. The old manage_asset MCP tool is gone.

A reference, references/mesh-reimport-materials.md, and the script scripts/mesh_material_slots.py handle static-mesh LOD reimport problems such as lost textures or gray default surfaces despite a correct component material, by inspecting and remapping material sections through the engine's Python API. The skill also notes that data assets and data tables have no dedicated service and are driven natively from Python, and it can call an external skills-manager tool for engine knowledge when one exists in the session.

When your agent uses it

  • Importing an image, mesh or other file from disk into the editor
  • Exporting a texture asset to a file
  • Finding out which asset is selected in the Content Browser
  • Fixing gray or default surfaces after a static-mesh reimport

Example prompts

  • “Import D:/art/crate.fbx into /Game/Props and keep the mesh name.”
  • “Export the T_Rock_Albedo texture to a PNG on disk.”
  • “My static mesh turns gray after reimporting its LODs, so inspect and remap the material slots.”

Requirements

  • Unreal Engine with the VibeUE plugin
  • The editor's Python scripting API

What it can do on your machine

Read from SKILL.md and the folder at commit dc051be. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    Ships 2 files in scripts/ (Python), which the agent can run.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Unreal Asset Import and Export loads about 6.5k tokens when it runs, and up to ~7k if it reads all its reference files. Until then it costs about 154 tokens; SKILL.md has 2,199 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~154
When it runs · the whole SKILL.md, loaded when a task matches
~6.5k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~7k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from kevinpbuckley/VibeUE at commit dc051be, republished under its MIT licence (© kevinpbuckley). 2,199 words, ~6,517 tokens.

Download SKILL.mdSave it as .claude/skills/asset-management/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
asset-management
description
Import files from disk (images, meshes, any format the editor imports), export textures, query the Content Browser selection, and check if an asset is open (AssetDiscoveryService). Search, load, save, move, rename, duplicate, and delete assets are handled by Unreal's native AssetTools toolset or EditorAssetLibrary. Use when the user asks to import an image, mesh or other file from disk, export a texture, query the Content Browser selection, or check whether an asset is open in an editor. Also use for static-mesh LOD reimport, section material mapping, or gray/default surfaces after reimport.
display_name
Asset Discovery & Management
vibeue_classes
AssetDiscoveryService
unreal_classes
EditorAssetLibrary, AssetRegistryHelpers

🧠 Brains complement: IF an unreal-engine-skills-manager tool (external MCP) exists in this session, call it with {action: "load", skill: "asset-management"} 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.

Asset Discovery & Management Skill

For static-mesh LOD reimport, lost textures or gray/default surfaces despite a correct component material, read mesh reimport material mappings. The bundled scripts/mesh_material_slots.py exposes explicit section inspection and remapping through the existing engine Python API; no native service rebuild.

🔀 Engine owns general asset ops now. In the Unreal 5.8 consolidation, searching, loading, saving, moving, renaming, duplicating, and deleting assets moved to Unreal's native AssetTools toolset (reach it via call_tool; run describe_toolset for its actions) — or you can drive unreal.EditorAssetLibrary / unreal.AssetRegistryHelpers directly from execute_python_code. The old manage_asset MCP tool is GONE. VibeUE's AssetDiscoveryService was trimmed to only the crash-safe delta the engine doesn't provide:

Kept on AssetDiscoveryServicePurpose
import_asset(src, dest_folder, name) → (path, err)Import an image, mesh or any importable file (folder + name)
import_texture(src, dest_asset_path)Same importer, full asset path
export_texture(asset_path, file_path)Export a texture to disk
get_primary_content_browser_selection() → AssetData or NonePrimary Content Browser selection
is_asset_open(asset_path) → boolWhether an asset is open in an editor

Everything else below (search_assets, list_assets_in_path, move_asset, duplicate_asset, delete_asset, save_asset, get_open_assets, get_asset_referencers, find_asset_by_path, asset_exists, …) was removed from AssetDiscoveryService — use the engine AssetTools toolset or EditorAssetLibrary / the Asset Registry.

Data Assets & Data Tables — no dedicated VibeUE service (issues #451, #452)

There is no DataAssetService / DataTableService. Drive them natively:

python
import unreal

# --- Data Assets (UPrimaryDataAsset / UDataAsset subclasses) ---
# Create: engine DataAssetTools toolset via call_tool (describe_toolset for the action), OR a factory.
da = unreal.load_asset("/Game/Data/DA_Thing")
val = da.get_editor_property("MyField")          # read
da.set_editor_property("MyField", 42)            # write — works for any UPROPERTY
unreal.EditorAssetLibrary.save_loaded_asset(da)

# --- Data Tables ---
dt = unreal.load_asset("/Game/Data/DT_Items")
names = unreal.DataTableFunctionLibrary.get_data_table_row_names(dt)   # row keys
# Read/write rows with the editor DataTable API:
#   unreal.DataTableFunctionLibrary.evaluate_curve_table_row(...) / get_data_table_column_as_string(dt, "Col")
# Engine DataTableTools (call_tool) covers add/remove/get rows + import/export CSV/JSON.

⚠️ Data Table gotchas (verified, #452): the row key ("Name") is reported as a column by some schema readers — it is the row id, not a data field. Writing a row with the wrong value type can be silently coerced — read the row back to confirm. There is no clear_rows; remove rows individually (engine DataTableTools) or re-import an empty CSV. An empty GameplayTag field serializes as "None".

Critical Rules

⚠️ delete_asset on a REFERENCED asset opens a modal dialog that wedges an unattended editor

EditorAssetLibrary.delete_asset asks "this asset is referenced, force delete?" through a modal window when anything points at the asset (a data asset holding the montage you are replacing, a Blueprint default, a level). Nobody answers it from MCP: the game thread stalls (308 s observed), every later call hangs, and the process has to be force-killed with the files removed from disk. Use the plugin's dialog-free delete instead:

python
# Refuses when referenced and tells you who:
result = unreal.AssetDiscoveryService.delete_asset_unattended("/Game/Anim/AM_Old", False)
# Delete anyway and null every reference (what the dialog's Force Delete does):
result = unreal.AssetDiscoveryService.delete_asset_unattended("/Game/Anim/AM_Old", True)
if not result.b_success:
    print(result.error_message)     # why it did not happen
    print(result.referencers)       # what pointed at the asset

The call returns an FUnattendedDeleteResult struct — result.b_success, result.referencers, result.error_message — so the reason ALWAYS survives, even on a refusal. (It used to return a bool with out-params, and Python maps a False return to None, which silently dropped the reason; that is fixed.) result.referencers is filled on a refusal AND on a forced delete, so you always see what pointed at the asset. Prefer creating the replacement under a NEW name and repointing references over force-deleting.

Even delete_asset_unattended(path, True) refuses a natively rooted in-memory object — it never prompts. Before deleting, the call does a conservative, non-mutating check: it looks at who holds the asset and refuses ONLY when a native GC root holds it directly — a UGCObjectReferencer, which in an agent session is a Python module-level global that created or loaded the asset earlier this session. That is the one case the engine's own force delete cannot clear, so it would stall on the modal "is in use" dialog (6+ minutes observed). When it refuses, the call returns b_success == False with those roots in result.referencers and an result.error_message explaining it. The fix is what the error says: release the Python globals holding it — del my_var, then unreal.SystemLibrary.collect_garbage() — and retry. Every OTHER in-memory referencer is left to the engine's real force delete, which clears it without prompting: on-disk asset references, the Blueprint-palette node spawners, and transient editor helpers like an anim data controller all delete fine. Read-only package files are also refused before the engine delete path, because Unreal can show a read-only-package prompt even when confirmation is disabled. Clear the filesystem/source-control read-only state explicitly, then retry.

The check never mutates state (it does not null any references before deciding), so a refusal leaves the asset and everything around it exactly as they were — safe to retry after releasing the global.

⚠️ Never delete_asset a Blueprint you loaded or compiled this session

EditorAssetLibrary.delete_asset on a Blueprint (Anim Blueprints especially) that is still loaded — which it is, if you created, compiled or read it earlier in the same script — fails inside ForceDeleteObjects and leaves the package half-deleted and corrupt:

Ensure condition failed: false [ObjectTools.cpp:4045]
Failed to unload all packages during ForceDeleteObjects - these packages are likely corrupt.
Consider restarting the editor, noting which assets remain and then deleting them from the
file system manually: /Game/Path/ABP_Thing

Every later call against that path then times out, and the editor typically has to be killed. The recovery is exactly what the message says — close the editor, delete the .uasset from disk, relaunch (watch for a ZenServer stall on the way back up) — so it costs several minutes.

The rebuild-an-asset pattern, instead of delete-then-create:

  • Write to a new name and swap references, or
  • Delete the file on disk while the editor is closed, then create it fresh, or
  • Edit the existing asset in place (clear the graph, re-add nodes) rather than recreating it.

The same caution applies to any asset currently open in an editor tab or referenced by a loaded level. Non-Blueprint assets you never loaded (textures, meshes written by a factory) delete fine.

⚠️ Out-Params Become Return Values in Python — Never Pass an AssetData Argument

get_primary_content_browser_selection is shaped like bool Func(FAssetData& Out) in C++ and is exposed to Python as () -> AssetData or None. Passing an AssetData argument raises TypeError.

python
# WRONG - TypeError: takes no arguments (1 given)
asset = unreal.AssetData()
unreal.AssetDiscoveryService.get_primary_content_browser_selection(asset)

# CORRECT - call with no out-arg, check the return for None
asset = unreal.AssetDiscoveryService.get_primary_content_browser_selection()
if asset:
    print(asset.asset_name)
🔀 Where each operation lives now
OperationUse
Search / find / list assetsengine AssetTools toolset via call_tool, or unreal.AssetRegistryHelpers.get_asset_registry()
Load / save / save-allunreal.EditorAssetLibrary.load_asset / save_asset / save_directory, or AssetTools
Move / rename / duplicate / deleteunreal.EditorAssetLibrary.rename_asset (move), duplicate_asset, delete_asset (unreferenced only — see the modal warning above), or AssetTools; unreal.AssetDiscoveryService.delete_asset_unattended for anything that may be referenced
Existence checkunreal.EditorAssetLibrary.does_asset_exist(path)
Referencers / dependenciesunreal.AssetRegistryHelpers.get_asset_registry().get_referencers(...)
Open an asset / list ALL open editorsEpic EditorAppToolset via call_tool (see below)
Import a file from disk (image, mesh, …)unreal.AssetDiscoveryService.import_asset / import_texture (see below)
Export a texture to diskunreal.AssetDiscoveryService.export_texture
Primary Content Browser selectionunreal.AssetDiscoveryService.get_primary_content_browser_selection()
Is an asset open in an editorunreal.AssetDiscoveryService.is_asset_open(path)
🔀 ALL open assets / ALL selections / open an asset — use Epic's EditorAppToolset

VibeUE covers the single/primary queries above; the list-all and open operations live on Epic's native EditorToolset.EditorAppToolset (call via call_tool; returns {"returnValue": [...]} of package-path strings). These are NOT Python-bound — they only work through call_tool:

NeedCall
All assets open in editorscall_tool("GetOpenAssets", "EditorToolset.EditorAppToolset")
All Content Browser selectionscall_tool("GetSelectedAssets", "EditorToolset.EditorAppToolset")
Open an asset in its editorcall_tool("OpenEditorForAsset", "EditorToolset.EditorAppToolset", {"assetPath": "/Game/.../BP_X"})
python
# "Show me all open Blueprints" = Epic GetOpenAssets + a type filter
opens = call_tool("GetOpenAssets", "EditorToolset.EditorAppToolset")["returnValue"]
bps = [p for p in opens if isinstance(unreal.load_asset(p), unreal.Blueprint)]

# "Open the selected asset" = VibeUE primary-selection + Epic OpenEditorForAsset
sel = unreal.AssetDiscoveryService.get_primary_content_browser_selection()
if sel:
    call_tool("OpenEditorForAsset", "EditorToolset.EditorAppToolset",
              {"assetPath": str(sel.package_name)})
🚨 Never list broad paths — a /Game listing can return 30,000+ assets

Listing every asset under /Game returns tens of thousands of entries and floods the conversation. Whether you go through the engine AssetTools toolset or EditorAssetLibrary.list_assets, always narrow first:

  • Filter by a specific subfolder (e.g. /Game/Blueprints/HUD), and by class where supported.
  • If you only need a count or sample, slice in Python before printing — never print the full array.
⚠️ EditorAssetLibrary Save Methods

There is no save_dirty_assets (AttributeError). The real options: unreal.EditorAssetLibrary.save_asset(path), save_directory(dir), save_loaded_asset(obj), save_loaded_assets([objs]). To save everything dirty, iterate or use the engine AssetTools toolset's save action.

⚠️ EditorAssetLibrary.list_assets Has No Class Filter

unreal.EditorAssetLibrary.list_assets(directory_path, recursive=True, include_folder=False) returns path strings only — there is no asset_class_names or any other class-filter kwarg (TypeError: invalid keyword argument). To list assets of one type, either filter the returned paths in Python (load each and check its class), or query the Asset Registry with a class filter via unreal.AssetRegistryHelpers.get_asset_registry().get_assets(...).

⚠️ UE 5.8 AssetData Property Names

get_primary_content_browser_selection() returns an AssetData. Read it with:

WRONG (old)CORRECT
asset.nameasset.asset_name
asset.pathasset.package_path
asset.asset_classasset.asset_class_path (a TopLevelAssetPath; compare .asset_name)
asset.object_pathf"{asset.package_name}.{asset.asset_name}"

AssetData has no object_path attribute (AttributeError). Build it from package_name + asset_name, or just use str(asset.package_name).

Show full SKILL.md (905 more words)Show less
⚠️ Importing Files From Disk — Use AssetDiscoveryService.import_asset

To bring a file from disk into the Content Browser, use AssetDiscoveryService.import_asset (or import_texture, which takes a full asset path and runs the same importer). It takes any format the editor imports, and saves what it imports:

  • Images (png, jpg, jpeg, bmp, tga, dds, exr, hdr, tiff, tif, psd, pcx) go through the texture factory's direct binary path and become a Texture2D.
  • Everything else (FBX, OBJ, glTF/GLB, audio, …) goes through an automated, synchronous AssetImportTask — no option dialogs.
python
import unreal

# Disk → Content Browser. Returns (asset_path, error); path is "" on failure.
path, err = unreal.AssetDiscoveryService.import_asset(
    "C:/Images/rocks.jpg", "/Game/UI/Textures", "T_Rocks")
print(path or err)

# A mesh takes the same call. Give a file that brings materials/textures a folder of its own.
path, err = unreal.AssetDiscoveryService.import_asset(
    "C:/Art/crate.fbx", "/Game/Props/Crate", "SM_Crate")
print(path or err)

What to expect:

  • Same-name assets are replaced, without a prompt. That includes the side assets a multi-asset file brings along: an FBX's materials and textures (and a skeletal mesh's Skeleton and PhysicsAsset) overwrite any asset of the same name already in the destination folder. Their names are only known once the importer has run, so there is no pre-check — import such files into an empty or dedicated folder.
  • The returned path is the main asset. For a file that brings several assets it is the mesh, not a material or texture; when the importer did not use the name you passed, the path carries the importer's name. List the folder (Asset Registry) to find the side assets.
  • The one context where an import would crash, and is refused instead. A synchronous AssetTools import waits by pumping the game thread's task queue. If the caller is itself running inside a game-thread task (the queue is already being processed), TaskGraph's RecursionGuard asserts and the editor goes down. import_asset checks for exactly that and returns an error naming RecursionGuard instead. execute_python_code and MCP tool calls do not run inside such a task, so imports from them go ahead. Calling unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks(...) yourself skips that check (and the save, and the main-asset pick) — prefer import_asset.

Need a source image to import? Editor screenshots live under the project's Saved/Screenshots (and Saved/VibeUE/Screenshots):

python
import os, unreal
shots = os.path.join(unreal.Paths.project_saved_dir(), "Screenshots")
print(os.listdir(shots) if os.path.isdir(shots) else "no screenshots yet")
⚠️ Asset Paths Must Be Content Browser Paths

Use /Game/... paths, not file system paths, everywhere except the disk side of import/export.

python
# WRONG - file system path
unreal.EditorAssetLibrary.does_asset_exist("C:/Projects/Content/BP_Player.uasset")

# CORRECT - content browser path
unreal.EditorAssetLibrary.does_asset_exist("/Game/Blueprints/BP_Player")
⚠️ Never Emulate Move/Rename with Duplicate + Delete

Duplicating creates a new asset identity. References stay pointed at the original, so deleting the original after a duplicate can break those references. Use a real move/rename (which fixes up references) instead:

python
import unreal

# EditorAssetLibrary.rename_asset performs a move + reference fixup
unreal.EditorAssetLibrary.rename_asset(
    "/Game/StateTree/STT_Rotate",
    "/Game/StateTree/Tasks/STT_Rotate")

(The engine AssetTools toolset exposes an equivalent move/rename action via call_tool.)

Creating Widget Blueprints

Use the engine's WidgetBlueprintFactory — a plain BlueprintFactory with a UserWidget parent creates a regular Blueprint, not a WidgetBlueprint (the removed BlueprintService.create_blueprint used to pick the UMG factory automatically):

python
factory = unreal.WidgetBlueprintFactory()
factory.set_editor_property("ParentClass", unreal.UserWidget)
wbp = unreal.AssetToolsHelpers.get_asset_tools().create_asset("WBP_Menu", "/Game/UI", None, factory)

For designing the widget afterwards (hierarchy, slots, bindings), load the umg-widgets skill.


Workflows

Search Pattern

Searching is an engine AssetTools job (via call_tool) — or query the Asset Registry directly:

python
import unreal

ar = unreal.AssetRegistryHelpers.get_asset_registry()

# All Blueprints under /Game (recursive). Use a class filter and a narrow path to avoid huge results.
f = unreal.ARFilter(
    package_paths=["/Game/Blueprints"],
    class_paths=[unreal.TopLevelAssetPath("/Script/Engine", "Blueprint")],
    recursive_paths=True)
for a in ar.get_assets(f)[:25]:
    print(f"{a.asset_name}: {a.package_path}")
Check Exists Pattern
python
import unreal

if unreal.EditorAssetLibrary.does_asset_exist("/Game/BP_Player"):
    print("Found")
else:
    print("Not found - create it")
Duplicate Pattern
python
import unreal

dup = unreal.EditorAssetLibrary.duplicate_asset("/Game/BP_Enemy", "/Game/BP_EnemyBoss")
if dup:
    print("Duplicated")
Move / Rename Pattern
python
import unreal

ok = unreal.EditorAssetLibrary.rename_asset(
    "/Game/StateTree/STT_Rotate",
    "/Game/StateTree/Tasks/STT_Rotate")
print("Moved (references fixed up)" if ok else "Move failed")
Save Pattern
python
import unreal

# Save a specific asset
unreal.EditorAssetLibrary.save_asset("/Game/BP_Player")

# Save a whole directory of dirty assets
unreal.EditorAssetLibrary.save_directory("/Game/Blueprints")
Check References Before Delete

Asset Registry referencer queries return package-name strings, not AssetData.

python
import unreal

ar = unreal.AssetRegistryHelpers.get_asset_registry()
refs = ar.get_referencers(
    "/Game/SM_Weapon",
    unreal.AssetRegistryDependencyOptions(include_hard_package_references=True))
if not refs:
    unreal.EditorAssetLibrary.delete_asset("/Game/SM_Weapon")
else:
    for ref in refs:          # ref is a package name, e.g. "/Game/Blueprints/BP_Player"
        print(f"In use by: {ref}")

⚠️ Deleting levels: delete_asset on a recently-loaded .umap can return True (asset gone from the registry) yet leave the package file on disk, so delete_directory on its folder then fails. After deleting level assets, verify the Content/... folder on disk and remove leftover .umap files manually.

⚠️ delete_asset false success is not limited to levels (issue #557). Blueprints with live references have also returned True while their files stayed on disk — and later touching such half-deleted assets ("files gone, editor memory ghosts") has crashed the editor. After ANY scripted delete, verify with a filesystem check (os.path.exists on the .uasset) or does_asset_exist, and never read properties (e.g. mesh bounds) off an asset you just deleted.

ℹ️ CaptureAssetImage cannot render Blueprints or Niagara systems ("Asset type does not support image capture"). To preview those, spawn them in the level on a clear spot, aim the viewport camera, and use the capture_image MCP tool; delete the preview actors after.

Import / Export Textures (VibeUE)
python
import unreal

# Import (disk → Content Browser). Returns (asset_path, error); asset_path is "" on failure.
# Pass a destination FOLDER + optional asset name.
path, err = unreal.AssetDiscoveryService.import_asset(
    "C:/Textures/logo.png", "/Game/Textures", "T_Logo")
print(path or err)

# import_texture(src, dest_asset_path) takes a full asset path and uses the same importer:
unreal.AssetDiscoveryService.import_texture("C:/Textures/logo.png", "/Game/Textures/T_Logo")

# Export (project → file system)
unreal.AssetDiscoveryService.export_texture("/Game/Textures/T_Logo", "C:/Exports/logo.png")
Editor State & Content Browser (VibeUE)
python
import unreal

# Is a specific asset open in an editor?
if unreal.AssetDiscoveryService.is_asset_open("/Game/BP_Player"):
    print("BP_Player is open")

# Primary Content Browser selection — NO out-arg, returns AssetData or None
asset = unreal.AssetDiscoveryService.get_primary_content_browser_selection()
if asset:
    print(f"Selected: {asset.asset_name} at {asset.package_path}")
    # Open it via the AssetEditorSubsystem (engine), loading the object first:
    obj = unreal.EditorAssetLibrary.load_asset(str(asset.package_name))
    unreal.get_editor_subsystem(unreal.AssetEditorSubsystem).open_editor_for_assets([obj])
else:
    print("Nothing selected")

For the full multi-selection set, open-editor lists, and search, use the engine AssetTools / AssetEditorSubsystem toolsets via call_tool.

Inspect the Selection's Class

asset.asset_class_path is a TopLevelAssetPath struct, not a string — compare its asset_name:

python
import unreal

asset = unreal.AssetDiscoveryService.get_primary_content_browser_selection()
if asset and str(asset.asset_class_path.asset_name) == "Blueprint":
    print(f"{asset.asset_name} is a Blueprint")
Create Non-Standard Asset Types (Factory Pattern)

Assets not covered by a VibeUE service (e.g., LandscapeGrassType) require AssetToolsHelpers + a factory. (create_asset imports nothing, so the import caveats above do not apply to it.)

python
import unreal

asset_tools = unreal.AssetToolsHelpers.get_asset_tools()

factory = unreal.LandscapeGrassTypeFactory()
lgt = asset_tools.create_asset("LGT_MyGrass", "/Game/Landscape", unreal.LandscapeGrassType, factory)

# Set properties via set_editor_property, then save
unreal.EditorAssetLibrary.save_asset("/Game/Landscape/LGT_MyGrass")

Tip: Use discover_python_module("unreal", name_filter="Factory") to find available factories.

Common Asset Class Names for Filtering
  • Blueprint, WidgetBlueprint
  • Texture2D, Material, MaterialInstanceConstant
  • StaticMesh, SkeletalMesh
  • DataTable, PrimaryDataAsset
  • LandscapeGrassType, LandscapeLayerInfoObject

Class names must match UE class names exactly (e.g., LandscapeGrassType, not GrassType). When a typed Asset Registry query unexpectedly returns 0, retry without the class filter and inspect each result's asset_class_path.asset_name to learn the real class name.

Sample scripts (run via execute_python_code)

  • scripts/find_and_save.txt — find an asset (Asset Registry / EditorAssetLibrary) and duplicate + save it.

Additional gotchas

  • unreal.Rotator(...) positional order is (roll, pitch, yaw) — pass by keyword.
  • unreal.AssetTools.create_asset(...) is a descriptor and throws; the working call is AssetToolsHelpers.get_asset_tools().create_asset(...).
  • EditDefaultsOnly properties cannot be written on instances from Python; a server-only UPROPERTY() with no Blueprint flag reads as "protected"; and when a bool bIsDead and a UFUNCTION IsDead() both map to is_dead, the property wins.
  • TInstancedStruct authoring: inst = unreal.InstancedStruct(); inst.import_text('/Script/<Module>.<Struct>(Field=...)'); a TSoftClassPtr UPROPERTY wants the loaded class, not a SoftClassPath.
  • LevelEditorPlaySettings is not in the Python stub — reach it via load_class(None, "/Script/UnrealEd.LevelEditorPlaySettings") and exact CamelCase property names.
  • Editor-world traces need a real world: line_trace_single(actor.get_world(), ...) (LevelEditorSubsystem.get_world() is a null context); HitResult.component/actor are read-protected, so read export_text().
  • World subsystems have no Python accessor — reach one via ObjectIterator(unreal.YourSubsystem) filtered on get_outer().get_path_name().
  • Never save_dirty_packages(True, True) — save by explicit path; a dirty package you did not touch is the user's work.

© kevinpbuckley, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 3 other files (scripts, references) in Content/Skills/asset-management of kevinpbuckley/VibeUE.

  • SKILL.md
  • references/mesh-reimport-materials.md
  • scripts/find_and_save.txt
  • scripts/mesh_material_slots.py

Open the folder on GitHubat commit dc051be

Compare with similar skills

Unreal Asset Import and Export 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.

Unreal Asset Import and Export compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Unreal Asset Import and Export this skillkevinpbuckley/VibeUE730—~6.5kAutomated safety check: PassMIT
Fmodel Unpackpa001024/dna-builder137—~2.6kAutomated safety check: PassMIT
Scenario Unreal Expertscenario-labs/skills946—~6.4kAutomated safety check: PassMIT
Unreal BridgeTornLux/UnrealBridge306—~8.4kAutomated safety check: NotesMIT
Unreal Blueprint Authoringflopperam/unreal-engine-mcp1.1k—~1.6kAutomated safety check: PassNone
Unreal Material and VFX Workflowflopperam/unreal-engine-mcp1.1k—~927Automated safety check: PassNone

Similar skills

  • Fmodel Unpack

    pa001024/dna-builder

    This skill documents how to use the fmodel-mcp toolkit (a CUE4Parse-based .NET CLI plus a thin Python MCP server) to inspect and export Unreal Engine game assets — pak files, textures, meshes…

    137 GitHub stars~2.6k tokensUpdated yesterday
    Game DevelopmentAuto-check passed
  • Scenario Unreal Expert

    scenario-labs/skills

    A skill your agent uses when an agent drives Unreal Engine 5.8 on a Mac for any task: Editor Python (the unreal module), headless UnrealEditor-Cmd -run=pythonscript jobs, Epic's Unreal MCP server…

    946 GitHub stars~6.4k tokensUpdated yesterday
    Game DevelopmentAuto-check passed
  • Unreal Bridge

    TornLux/UnrealBridge

    Execute Python scripts inside a running Unreal Engine 5.3+ editor via TCP bridge.

    306 GitHub stars~8.4k tokensUpdated 10 days ago
    Game DevelopmentAuto-check: notes
  • Unreal Blueprint Authoring

    flopperam/unreal-engine-mcp

    Walks an agent through creating and editing Unreal Engine Blueprints with the Flopperam MCP's bp_* tools, from inspection to commit and verification.

    1.1k GitHub stars~1.6k tokensUpdated 3 mo ago
    Game DevelopmentAuto-check passed
  • Unreal Material and VFX Workflow

    flopperam/unreal-engine-mcp

    Walks an Unreal Engine MCP agent through building materials, Niagara particle systems, Chaos destruction, and curve assets with inspect-then-edit steps.

    1.1k GitHub stars~927 tokensUpdated 3 mo ago
    Game DevelopmentAuto-check passed
  • Text To 3D Asset

    LaurentiuGabriel/unreal-game-assets-creation-skill

    Generate a game-ready 3D asset by running the local AI pipeline sequentially: Fooocus (SDXL text-to-image) - Hunyuan3D-2 (image-to-textured-GLB) - optional Blender FBX convert + Unreal import.

    148 GitHub stars~2.1k tokensUpdated 2 mo ago
    Game DevelopmentAuto-check passed

More from kevinpbuckley/VibeUE

All 39 skills in this repo
  • Unreal Animation Bone Editor

    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.

    730 GitHub stars~1.3k tokensUpdated 3 days ago
    Auto-check passed
  • Unreal Animation Montage

    kevinpbuckley/VibeUE

    Creates and edits Unreal Engine Animation Montages through AnimMontageService: sections, slots, segments, branching points, notifies and blend settings.

    730 GitHub stars~3.6k tokensUpdated 3 days ago
    Auto-check passed
  • Unreal AnimSequence Editor

    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.

    730 GitHub stars~3.2k tokensUpdated 3 days ago
    Auto-check passed
  • Unreal Engine Settings Control

    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.

    730 GitHub stars~1.3k tokensUpdated 3 days ago
    Auto-check passed
  • Unreal Enhanced Input Setup

    kevinpbuckley/VibeUE

    Creates and wires Unreal Engine Enhanced Input assets through VibeUE's InputService: Input Actions, Mapping Contexts, key bindings, triggers and modifiers.

    730 GitHub stars~2.4k tokensUpdated 3 days ago
    Auto-check passed
  • Unreal Enum and Struct Editor

    kevinpbuckley/VibeUE

    Creates, edits and inspects Unreal Engine UserDefinedEnums and UserDefinedStructs through Python, including adding values or members and reading internal versus display names.

    730 GitHub stars~2.3k tokensUpdated 3 days ago
    Auto-check passed

Questions about Unreal Asset Import and Export

What does Unreal Asset Import and Export do?

Imports files into Unreal Engine, exports textures, reads the Content Browser selection and checks open assets via VibeUE, plus mesh reimport material fixes. 8 consolidated general asset operations, the engine's native AssetTools toolset or EditorAssetLibrary handles searching, loading, saving, moving, renaming, duplicating and deleting assets, so this skill covers only the remaining AssetDiscoveryService calls: import_asset and import_texture for bringing in images, meshes or other importable files, export_texture, get_primary_content_browser_selection and is_asset_open. The old manage_asset MCP tool is gone.

When should I use Unreal Asset Import and Export?

Unreal Asset Import and Export fits situations like: importing an image, mesh or other file from disk into the editor; exporting a texture asset to a file; finding out which asset is selected in the Content Browser; fixing gray or default surfaces after a static-mesh reimport.

How do I install Unreal Asset Import and Export in Claude Code?

Run `npx skills add kevinpbuckley/VibeUE --skill asset-management -a claude-code`. Or copy the skill folder (Content/Skills/asset-management in kevinpbuckley/VibeUE) into .claude/skills/asset-management in your project. Claude Code loads it when a task matches its description.

How do I install Unreal Asset Import and Export in Codex?

Run `npx skills add kevinpbuckley/VibeUE --skill asset-management -a codex`. Or copy the skill folder (Content/Skills/asset-management in kevinpbuckley/VibeUE) into .agents/skills/asset-management in your project. Codex loads it when a task matches its description.

Can I use Unreal Asset Import and Export in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add kevinpbuckley/VibeUE --skill asset-management -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/asset-management, .gemini/skills/asset-management, .github/skills/asset-management and .opencode/skills/asset-management in your project.

What does Unreal Asset Import and Export need to run?

Going by SKILL.md and its folder, Unreal Asset Import and Export needs Python for the scripts in its folder. Our summary lists: Unreal Engine with the VibeUE plugin; The editor's Python scripting API.

Does Unreal Asset Import and Export access the network?

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.

Is Unreal Asset Import and Export safe to install?

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.

What licence does Unreal Asset Import and Export use?

Unreal Asset Import and Export is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Unreal Asset Import and Export use?

About 6.5k tokens (SKILL.md is roughly 26k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 517 tokens, read only when the agent opens those files.

What are the alternatives to Unreal Asset Import and Export?

Skills that share tags, products or a category with Unreal Asset Import and Export: Fmodel Unpack (pa001024/dna-builder, 137 stars), Scenario Unreal Expert (scenario-labs/skills, 946 stars), Unreal Bridge (TornLux/UnrealBridge, 306 stars) and Unreal Blueprint Authoring (flopperam/unreal-engine-mcp, 1.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Unreal Asset Import and Export?

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.