Skip to content

Blender Room Workflow

Summary: Export UEternalRoomData assets from Unreal to JSON, then import into Blender to generate reference geometry (bounds, grid, door markers). This ensures room geometry aligns with ProceduralDungeon's spatial requirements before USD export back to Unreal.

Table of Contents


Why This Workflow

Problem

Room geometry created in Blender must align precisely with ProceduralDungeon's grid system:

Requirement Without Workflow With Workflow
Door positions Manual calculation Visual markers
Room bounds Guesswork Wireframe reference
Grid alignment Error-prone Snap to 10m grid
Coordinate conversion UU ↔ meters confusion Pre-calculated references

Benefits

Benefit Description
Visual Reference See exact bounds, doors, grid while modeling
Accurate Placement Door empties mark precise connection points
Export Clean Reference geometry auto-excluded from USD
Bidirectional Data flows Unreal → Blender → Unreal

Architecture Overview

┌────────────────────────────────────────────────────────────────────┐
│                         UNREAL ENGINE                               │
│  ┌──────────────────────┐                                          │
│  │  UEternalRoomData    │  Right-click → "Export to JSON"          │
│  │  • FirstPoint        │         │                                │
│  │  • SecondPoint       │         ▼                                │
│  │  • Doors[]           │  {Project}/Intermediate/RoomExport/*.json│
│  └──────────────────────┘                                          │
└────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────┐
│                           BLENDER                                   │
│  ┌──────────────────────┐                                          │
│  │  import_room_data.py │  File → Import → Eternal Room Data       │
│  │  (Add-on)            │         │                                │
│  └──────────────────────┘         ▼                                │
│  ┌────────────────────────────────────────────────────────────┐    │
│  │ Room_Name (Collection)                                      │    │
│  │  ├─ _Markers (hidden from render)                          │    │
│  │  │   ├─ _Bounds_RoomName (wireframe cube)                  │    │
│  │  │   ├─ _Grid_RoomName (edge lines)                        │    │
│  │  │   ├─ Door_North_0 (empty + box)                         │    │
│  │  │   └─ Door_South_1 (empty + box)                         │    │
│  │  └─ Geo (user geometry goes here)                          │    │
│  └────────────────────────────────────────────────────────────┘    │
│                                    │                                │
│                         USD Export (Visible Only)                   │
│                         _Markers excluded                           │
└────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────┐
│                         UNREAL ENGINE                               │
│  Content/UsdAssets/Rooms/{Domain}/Room_*.usd                       │
│  → Referenced by UEternalRoomData                                   │
└────────────────────────────────────────────────────────────────────┘

Coordinate System

ProceduralDungeon Spatial Constants

Parameter Unreal Units Blender (meters)
Room Unit (cell) 1000 × 1000 × 400 10m × 10m × 4m
Door Size 40 × 640 × 400 0.4m × 6.4m × 4m

ToWorldLocation Formula

The plugin converts grid cells to world coordinates using:

WorldPos = RoomUnit * (RoomPoint - (0.5, 0.5, 0))
Axis Offset Reason
X -0.5 Room centered on X
Y -0.5 Room centered on Y
Z 0 Floor at Z=0, no centering

Example Conversion

For FirstPoint=(-1, -1, 0) and SecondPoint=(5, 2, 3):

Point Grid World (UU) World (meters)
First (-1, -1, 0) (-1500, -1500, 0) (-15m, -15m, 0m)
Second (5, 2, 3) (4500, 1500, 1200) (45m, 15m, 12m)
Center - (1500, 0, 600) (15m, 0m, 6m)

Door Directions

Direction Unreal Axis Placement
North +X Max X boundary
East +Y Max Y boundary
South -X Min X boundary
West -Y Min Y boundary

JSON Schema

Exported JSON contains all data needed to reconstruct reference geometry:

Field Type Description
room_name string Asset name
room_type string Enum value as string
first_point {x,y,z} Grid cell min bound
second_point {x,y,z} Grid cell max bound
doors array Door definitions
room_unit {x,y,z} Cell size in UU
door_size {x,y,z} Door opening size in UU

Door Object

Field Type Description
position {x,y,z} Cell position
direction string North/East/South/West
type string UDoorType asset name

Unreal Export

Right-Click Context Menu

  1. Select UEternalRoomData asset(s) in Content Browser
  2. Right-click → "Export to JSON for Blender"
  3. JSON saved to {Project}/Intermediate/RoomExport/{AssetName}.json
  4. Notification confirms export path

Implementation

The FAssetTypeActions_EternalRoomData class adds the context menu action:

UEternalRoomData (selected)
ExecuteExportToJson()
        ├─ Read FirstPoint, SecondPoint from URoomData base
        ├─ Read Doors array (FDoorDef)
        ├─ Convert EDoorDirection to string
        ├─ Build JSON structure
{Project}/Intermediate/RoomExport/{Name}.json

Blender Import

Installation

  1. Edit → Preferences → Add-ons → Install
  2. Select Tools/Blender/import_room_data.py
  3. Enable "Eternal Room Importer"

Usage

  1. File → Import → Eternal Room Data (.json)
  2. Select exported JSON file
  3. Collection hierarchy created automatically

Generated Objects

Object Type Purpose
_Bounds_{Name} Wireframe cube Room boundary visualization
_Grid_{Name} Edge mesh 10m cell grid lines
Door_{Dir}_{N} Empty (arrow) Door position and facing
_DoorBox_{...} Wireframe cube Door opening size

Collection Structure

Room_Name/
├─ _Markers/          ← hide_render=True (excluded from USD)
│   ├─ _Bounds_*
│   ├─ _Grid_*
│   ├─ Door_North_0
│   ├─ _DoorBox_Door_North_0
│   └─ ...
└─ Geo/               ← User models geometry here
    └─ (your meshes)

Custom Properties

Door empties store metadata for round-trip workflows:

Property Example Purpose
door_direction "North" Direction enum
door_cell_x/y/z 4, 0, 0 Grid position
door_type "Standard" UDoorType name

USD Export Back to Unreal

Export Settings

Setting Value Reason
Selection Only ON Export specific room
Visible Only ON Excludes _Markers (hide_render=True)
Export Scale 100.0 Meters → centimeters
Apply Modifiers ON Bake geometry
Triangulate ON Unreal compatibility

Workflow

  1. Select Geo collection contents
  2. Verify _Markers has hide_render=True (automatic)
  3. File → Export → USD
  4. Save to Content/UsdAssets/Rooms/{Domain}/
  5. Import in Unreal, reference from UEternalRoomData

What Gets Exported

Collection Exported Why
Geo Yes User geometry
_Markers No hide_render=True
Any _ prefixed No Convention + visibility

Source References

Unreal (Editor Module)

Component Location
FAssetTypeActions_EternalRoomData Source/ProjectEternalEditor/Public/RoomDataExporter/AssetTypeActions_EternalRoomData.h
Export implementation Source/ProjectEternalEditor/Private/RoomDataExporter/AssetTypeActions_EternalRoomData.cpp
Module registration Source/ProjectEternalEditor/Private/ProjectEternalEditor.cpp

Blender

Component Location
Import add-on Tools/Blender/import_room_data.py

ProceduralDungeon Plugin

Component Location
ToWorldLocation() Plugins/ProceduralDungeon/Source/ProceduralDungeon/Private/ProceduralDungeonUtils.cpp
FDoorDef Plugins/ProceduralDungeon/Source/ProceduralDungeon/Public/ProceduralDungeonTypes.h
EDoorDirection Plugins/ProceduralDungeon/Source/ProceduralDungeon/Public/ProceduralDungeonTypes.h


Recent Changes

Date Change Impact
2026-01-24 Initial implementation Added export action and Blender importer
2026-01-24 Fixed coordinate conversion Match ProceduralDungeon's ToWorldLocation formula
2026-01-24 USD export exclusion _Markers hidden via hide_render=True