Capture screenshots of the editor window, viewports, and blueprints for AI vision analysis
| Method | Use Case |
|---|---|
capture_editor_window(path) | DEFAULT — use this for everything. Synchronous. Captures the whole editor window including any open tab (level viewport, Blueprint, Material, etc.) |
capture_active_window(path) | Whatever window is currently focused |
get_active_window_title() | Check what's in focus |
get_open_editor_tabs() | List open asset editors |
capture_viewport(path, w, h) | ❌ DO NOT USE from Python — asynchronous, file never appears on disk during a Python call. Returns success=False with an explanation. |
Capture the current view by default — do NOT move the camera unless the user explicitly asks you to frame something a specific way. Moving the camera is disruptive and requires the user to manually reset their view.
The ActorService provides methods to calculate and apply camera positions that frame actors:
import unreal
actor_service = unreal.ActorService
# Move viewport camera to frame an actor from a specific direction
# Use unreal.ViewDirection (NOT unreal.EViewDirection — that prefix does not exist)
# Directions: TOP, BOTTOM, LEFT, RIGHT, FRONT, BACK
view = actor_service.get_actor_view_camera("MyLandscape", unreal.ViewDirection.TOP)
# Camera is now positioned — take screenshot immediately
# Calculate view without moving camera (for planning)
view = actor_service.calculate_actor_view("MyActor", unreal.ViewDirection.FRONT, 1.5)
# view.camera_location, view.camera_rotation available
# Apply when ready:
actor_service.set_viewport_camera(view.camera_location, view.camera_rotation)
# Directly set camera to any position/rotation (avoid this — easy to miss the subject)
actor_service.set_viewport_camera(
unreal.Vector(1000, 2000, 500),
unreal.Rotator(-45, 0, 0)
)
⚠️ Critical: Always use
unreal.ViewDirection.FRONT— neverunreal.EViewDirection.FRONT. TheEprefix does not exist and will raiseAttributeError.⚠️ Avoid guessing camera coordinates with
set_viewport_camera. Manual positions likeVector(1200,-1200,600)almost always capture only sky or empty space. Always preferget_actor_view_camerawhich auto-calculates position from the actor's bounding box.For a diagonal/3-quarter view, use
calculate_actor_viewto get real bounds first, then offset from that position using trig — never guess coordinates. See thelevel-actorsskill for the diagonal camera pattern.
View directions:
| Direction | Camera Position | Looking |
|---|---|---|
TOP | Above actor | Straight down (-Z) |
BOTTOM | Below actor | Straight up (+Z) |
LEFT | Left of actor (-Y) | Toward +Y |
RIGHT | Right of actor (+Y) | Toward -Y |
FRONT | Front of actor (+X) | Toward -X |
BACK | Behind actor (-X) | Toward +X |
Padding multiplier: 1.0 = tight fit, 1.2 = 20% padding (default), 2.0 = double distance Camera distance is automatically calculated from the actor's bounding box to fit it in view.
success (bool) - Whether calculation succeededcamera_location (Vector) - Calculated camera positioncamera_rotation (Rotator) - Calculated camera rotationview_direction (ViewDirection) - Direction usedactor_center (Vector) - Actor bounds centeractor_extent (Vector) - Actor bounds half-extentview_distance (float) - Distance from camera to actor centerUse UnrealEditorSubsystem to get/set the viewport camera:
import unreal
editor_subsys = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
# Get current camera
camera_info = editor_subsys.get_level_viewport_camera_info()
if camera_info:
cam_loc, cam_rot = camera_info
# Set camera to a new position/rotation
new_location = unreal.Vector(x, y, z)
new_rotation = unreal.Rotator(pitch, yaw, roll)
editor_subsys.set_level_viewport_camera_info(new_location, new_rotation)
import unreal
def frame_actor_for_screenshot(actor, distance=500.0, pitch=-25.0):
"""Position camera to look at an actor from a good angle."""
editor_subsys = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
# Get actor bounds for center point
origin, extent = actor.get_actor_bounds(False)
# Position camera behind and above, looking at the actor
yaw = 0.0 # Face default direction; adjust as needed
rot = unreal.Rotator(pitch, yaw, 0.0)
forward = rot.get_forward_vector()
cam_loc = origin - (forward * distance)
editor_subsys.set_level_viewport_camera_info(cam_loc, rot)
import unreal
# capture_editor_window is synchronous — file is ready immediately after the call
result = unreal.ScreenshotService.capture_editor_window("my_capture")
# Path is auto-normalized: saves to ProjectSaved/VibeUE/Screenshots/my_capture.png
if result.success:
print(f"SCREENSHOT_SAVED: {result.file_path}")
After executing, use attach_image(file_path=result.file_path) to analyze.
⚠️ NEVER use
capture_viewportfrom Python. It queues a write for the next engine render frame, which will not occur while Python is running on the game thread. The file will never appear on disk.capture_viewportnow returnssuccess=Falsewith an explanation — if you see that, switch tocapture_editor_windowimmediately. Do NOT retrycapture_viewport.
import unreal
tabs = unreal.ScreenshotService.get_open_editor_tabs()
for tab in tabs:
print(f"{tab.tab_label} ({tab.tab_type})")
if unreal.ScreenshotService.is_editor_window_active():
print("Editor is focused")