editor.foliage
Fourteen methods covering UE's full foliage pipeline: six procedural methods drive UProceduralFoliageSpawner / AProceduralFoliageVolume for AI-directed ecosystem generation, and eight legacy methods manage instance-based foliage types (CRUD, property editing, bounded-volume queries and removal, direct instance placement). AI agents reach through this namespace to stand up procedural foliage ecosystems and to spot-edit or sweep legacy instances at the volume level.
Always available. The foliage handler lives in the Foliage runtime module, present on stock UE. No separate plugin required.
Method summary
| Method | Group | Mutating | Purpose |
|---|---|---|---|
getProceduralVolumes | Procedural | no | Paginated list of ProceduralFoliageVolume actors with spawner config. |
getProceduralVolumeInfo | Procedural | no | Deep inspection of one volume with per-foliage-type procedural settings. |
setProceduralVolumeSettings | Procedural | yes | Configure a volume's component and spawner properties. |
resimulateProceduralVolume | Procedural | yes | Clear instances and resimulate the volume. |
clearProceduralVolume | Procedural | yes | Remove procedural instances without resimulating. |
simulateSpawner | Procedural | yes | Run the spawner's tile pre-computation without placing instances. |
getTypes | Legacy | no | All foliage types with instance counts. |
getInstances | Legacy | no | Query instances within a bounding box. |
removeInstances | Legacy | yes | Remove instances within a bounding box. |
addType | Legacy | yes | Register a new foliage type from a static mesh. |
removeType | Legacy | yes | Unregister a foliage type and its instances. |
getTypeProperties | Legacy | no | All properties of a foliage type, grouped by category. |
setTypeProperties | Legacy | yes | Write properties on a foliage type. |
addInstances | Legacy | yes | Programmatically place instances at specified transforms. |
Procedural Foliage (6 methods)
editor.foliage.getProceduralVolumes
List all ProceduralFoliageVolume actors in the level with spawner configuration and status. Paginates large worlds via limit/offset.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
limit | number | No | Max items (1-5000, default 500). |
offset | number | No | Items to skip (default 0). |
Returns: { volumes, count, total, limit, offset, has_more }. Each volume carries actor_name, actor_path, spawner_path, random_seed, tile_size, num_unique_tiles, minimum_quad_tree_size, tile_overlap, has_spawned, five surface filter flags, show_debug_tiles, a foliage_types array with mesh paths, and bounds.
Example Request:
{ "jsonrpc": "2.0", "id": 1, "method": "editor.foliage.getProceduralVolumes", "params": { "limit": 100 } } Example Response:
{
"jsonrpc": "2.0", "id": 1,
"result": {
"volumes": [
{
"actor_name": "PF_Forest01", "actor_path": "/Game/Maps/L_Main.L_Main:PersistentLevel.PF_Forest01",
"spawner_path": "/Game/Foliage/FS_Forest.FS_Forest",
"random_seed": 42, "tile_size": 6400, "num_unique_tiles": 8, "minimum_quad_tree_size": 1600, "tile_overlap": 200,
"has_spawned": true,
"allow_landscape": true, "allow_bsp": false, "allow_static_mesh": true, "allow_translucent": false, "allow_foliage": false,
"show_debug_tiles": false,
"foliage_types": [ { "mesh_path": "/Game/Foliage/Trees/SM_OakTree.SM_OakTree" } ],
"bounds": { "min": [0, 0, 0], "max": [6400, 6400, 400] }
}
],
"count": 1, "total": 1, "limit": 100, "offset": 0, "has_more": false
}
} editor.foliage.getProceduralVolumeInfo
Deep inspection of a single procedural foliage volume with per-foliage-type procedural settings (seed density, spread distance, variance, age, scale range, overlap priority, etc.).
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
actor | string | Yes | Volume actor name or label. |
Returns: Every field from getProceduralVolumes for one volume, plus per-foliage-type procedural settings (initial_seed_density, num_steps, seeds_per_step, average_spread_distance, spread_variance, collision_radius, shade_radius, max_age, max_initial_age, overlap_priority, can_grow_in_shade, spawns_in_shade, procedural_scale {min, max}) and associated blocking_volumes.
Example Request:
{ "jsonrpc": "2.0", "id": 2, "method": "editor.foliage.getProceduralVolumeInfo", "params": { "actor": "PF_Forest01" } } Example Response:
{
"jsonrpc": "2.0", "id": 2,
"result": {
"actor_name": "PF_Forest01",
"foliage_types": [
{ "mesh_path": "/Game/Foliage/Trees/SM_OakTree.SM_OakTree", "initial_seed_density": 0.05, "num_steps": 10, "seeds_per_step": 50, "average_spread_distance": 1200, "spread_variance": 300, "collision_radius": 400, "procedural_scale": { "min": 0.8, "max": 1.3 } }
],
"blocking_volumes": []
}
} editor.foliage.setProceduralVolumeSettings
Configure a procedural volume's component and spawner settings. Any subset of the named parameters may be passed.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
actor | string | Yes | Volume actor name or label. |
tileOverlap | number | No | Tile overlap in cm. |
allowLandscape | bool | No | Place on landscape. |
allowBSP | bool | No | Place on BSP. |
allowStaticMesh | bool | No | Place on static meshes. |
allowTranslucent | bool | No | Place on translucent. |
allowFoliage | bool | No | Place on other foliage. |
showDebugTiles | bool | No | Visualize tile layout. |
randomSeed | number | No | Spawner random seed. |
tileSize | number | No | Spawner tile size in cm. |
numUniqueTiles | number | No | Unique tile count. |
minimumQuadTreeSize | number | No | Minimum quad-tree size. |
Returns: { success: true, properties_changed: N }.
Example Request:
{
"jsonrpc": "2.0", "id": 3,
"method": "editor.foliage.setProceduralVolumeSettings",
"params": { "actor": "PF_Forest01", "tileOverlap": 400, "allowLandscape": true, "randomSeed": 100 }
} Example Response:
{ "jsonrpc": "2.0", "id": 3, "result": { "success": true, "properties_changed": 3 } } editor.foliage.resimulateProceduralVolume
Clear all procedural instances and resimulate the volume. Blocks until simulation completes.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
actor | string | Yes | Volume actor name or label. |
Returns: { success: true, instance_count: N, elapsed_ms: X }.
Example Request:
{ "jsonrpc": "2.0", "id": 4, "method": "editor.foliage.resimulateProceduralVolume", "params": { "actor": "PF_Forest01" } } Example Response:
{ "jsonrpc": "2.0", "id": 4, "result": { "success": true, "instance_count": 4182, "elapsed_ms": 2918 } } editor.foliage.clearProceduralVolume
Remove all procedurally-generated instances from a volume without resimulating.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
actor | string | Yes | Volume actor name or label. |
Returns: { success: true }.
Example Request:
{ "jsonrpc": "2.0", "id": 5, "method": "editor.foliage.clearProceduralVolume", "params": { "actor": "PF_Forest01" } } Example Response:
{ "jsonrpc": "2.0", "id": 5, "result": { "success": true } } editor.foliage.simulateSpawner
Run the spawner's tile pre-computation (Simulate) without placing instances.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
actor | string | Yes | Volume actor name or label. |
numSteps | number | No | Override simulation steps. Default: max from foliage types. |
Returns: { success: true, num_steps: N }.
Example Request:
{ "jsonrpc": "2.0", "id": 6, "method": "editor.foliage.simulateSpawner", "params": { "actor": "PF_Forest01", "numSteps": 12 } } Example Response:
{ "jsonrpc": "2.0", "id": 6, "result": { "success": true, "num_steps": 12 } } Legacy Foliage (8 methods)
editor.foliage.getTypes
List every foliage type in the level with instance counts.
No parameters.
Returns: { foliage_types: [{type_name, mesh_path, actor_class, instance_count, foliage_type_path}], count }.
Example Request:
{ "jsonrpc": "2.0", "id": 7, "method": "editor.foliage.getTypes" } Example Response:
{
"jsonrpc": "2.0", "id": 7,
"result": {
"foliage_types": [
{ "type_name": "SM_GrassClump01", "mesh_path": "/Game/Foliage/Grass/SM_GrassClump01.SM_GrassClump01", "actor_class": "FoliageType_InstancedStaticMesh", "instance_count": 2412, "foliage_type_path": "/Game/Foliage/Grass/FT_GrassClump01.FT_GrassClump01" }
],
"count": 1
}
} editor.foliage.getInstances
Query foliage instances within a bounding box. Optionally filter by type name or mesh path.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
box_min | object | Yes | {x, y, z} minimum corner. |
box_max | object | Yes | {x, y, z} maximum corner. |
type_name | string | No | Filter by foliage type name. |
mesh_path | string | No | Filter by mesh path. |
Returns: { instances: [{type_name, location, rotation, scale}], count }.
Example Request:
{
"jsonrpc": "2.0", "id": 8,
"method": "editor.foliage.getInstances",
"params": { "box_min": { "x": 0, "y": 0, "z": 0 }, "box_max": { "x": 1000, "y": 1000, "z": 500 }, "type_name": "SM_GrassClump01" }
} Example Response:
{
"jsonrpc": "2.0", "id": 8,
"result": {
"instances": [
{ "type_name": "SM_GrassClump01", "location": [320, 421, 88], "rotation": [0, 45, 0], "scale": [1.1, 1.1, 1.1] }
],
"count": 1
}
} editor.foliage.removeInstances
Remove foliage instances within a bounding box. Optionally filter by type name.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
box_min | object | Yes | {x, y, z} minimum corner. |
box_max | object | Yes | {x, y, z} maximum corner. |
type_name | string | No | Filter by type name. |
Returns: { removed_count: N, success: true }.
Example Request:
{
"jsonrpc": "2.0", "id": 9,
"method": "editor.foliage.removeInstances",
"params": { "box_min": { "x": 0, "y": 0, "z": 0 }, "box_max": { "x": 500, "y": 500, "z": 500 } }
} Example Response:
{ "jsonrpc": "2.0", "id": 9, "result": { "removed_count": 412, "success": true } } editor.foliage.addType
Register a new foliage type from a static mesh.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
mesh | string | Yes | Full UObject path to a UStaticMesh. |
Returns: { success: true, foliage_type_path, mesh_path }.
Example Request:
{ "jsonrpc": "2.0", "id": 10, "method": "editor.foliage.addType", "params": { "mesh": "/Game/Foliage/Grass/SM_GrassClump01.SM_GrassClump01" } } Example Response:
{
"jsonrpc": "2.0", "id": 10,
"result": { "success": true, "foliage_type_path": "/Game/Foliage/Grass/FT_GrassClump01.FT_GrassClump01", "mesh_path": "/Game/Foliage/Grass/SM_GrassClump01.SM_GrassClump01" }
} editor.foliage.removeType
Unregister a foliage type and every instance of it in the level.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
foliage_type | string | Yes | Foliage type path (from getTypes). |
Returns: { success: true }.
Example Request:
{ "jsonrpc": "2.0", "id": 11, "method": "editor.foliage.removeType", "params": { "foliage_type": "/Game/Foliage/Grass/FT_GrassClump01.FT_GrassClump01" } } Example Response:
{ "jsonrpc": "2.0", "id": 11, "result": { "success": true } } editor.foliage.getTypeProperties
Read all properties of a foliage type, grouped by category (painting, placement, procedural, rendering, instanced_static_mesh).
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
foliage_type | string | Yes | Foliage type path. |
Returns: { painting: {...}, placement: {...}, procedural: {...}, rendering: {...}, instanced_static_mesh: {...} }. Categories:
- painting -- density, density_adjustment_factor, radius
- placement -- scale_x/y/z (min/max), scaling, z_offset, align_to_normal, align_max_angle, random_yaw, random_pitch_angle, ground_slope_angle, height, collision_with_world, collision_scale, mobility, landscape_layers, exclusion_landscape_layers
- procedural -- collision_radius, shade_radius, num_steps, seeds_per_step, initial_seed_density, average_spread_distance, spread_variance, overlap_priority, max_age, max_initial_age, procedural_scale, can_grow_in_shade, spawns_in_shade
- rendering -- cast_shadow, cast_dynamic_shadow, cast_static_shadow, cull_distance, enable_density_scaling, enable_cull_distance_scaling, use_as_occluder, receives_decals, visible_in_ray_tracing, lightmap_type
- instanced_static_mesh (ISM types only) -- mesh_path, override_materials, nanite_override_materials
Example Request:
{ "jsonrpc": "2.0", "id": 12, "method": "editor.foliage.getTypeProperties", "params": { "foliage_type": "/Game/Foliage/Grass/FT_GrassClump01.FT_GrassClump01" } } Example Response:
{
"jsonrpc": "2.0", "id": 12,
"result": {
"painting": { "density": 150.0, "density_adjustment_factor": 1.0, "radius": 0.0 },
"placement": { "scale_x": { "min": 0.8, "max": 1.2 }, "scaling": "Uniform", "align_to_normal": true },
"procedural": { "collision_radius": 40.0, "shade_radius": 40.0, "num_steps": 4 },
"rendering": { "cast_shadow": true, "cull_distance": { "min": 0, "max": 10000 }, "visible_in_ray_tracing": false },
"instanced_static_mesh": { "mesh_path": "/Game/Foliage/Grass/SM_GrassClump01.SM_GrassClump01" }
}
} editor.foliage.setTypeProperties
Write properties on a foliage type. Pass any subset of property names from getTypeProperties. Bumps the type's ChangeCount to trigger visual refresh.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
foliage_type | string | Yes | Foliage type path. |
density | number | No | Instances per 1000x1000 area. |
scale_x | object | No | {min, max}. |
collision_radius | number | No | Procedural collision radius. |
any property from getTypeProperties | varies | No | Name-matched reflection write. |
Returns: { success: true, properties_changed: N }.
Example Request:
{
"jsonrpc": "2.0", "id": 13,
"method": "editor.foliage.setTypeProperties",
"params": { "foliage_type": "/Game/Foliage/Grass/FT_GrassClump01.FT_GrassClump01", "density": 220.0, "collision_radius": 35.0 }
} Example Response:
{ "jsonrpc": "2.0", "id": 13, "result": { "success": true, "properties_changed": 2 } } editor.foliage.addInstances
Programmatically place foliage instances at specified transforms. Capped at 1000 instances per call.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
foliage_type | string | Yes | Foliage type path. |
transforms | array | Yes | Array of {location: {x,y,z}, rotation?: {pitch,yaw,roll}, scale?: {x,y,z}}. Max 1000. |
Returns: { success: true, added_count: N }.
Example Request:
{
"jsonrpc": "2.0", "id": 14,
"method": "editor.foliage.addInstances",
"params": {
"foliage_type": "/Game/Foliage/Grass/FT_GrassClump01.FT_GrassClump01",
"transforms": [
{ "location": { "x": 100, "y": 200, "z": 0 }, "rotation": { "pitch": 0, "yaw": 30, "roll": 0 }, "scale": { "x": 1.1, "y": 1.1, "z": 1.0 } }
]
}
} Example Response:
{ "jsonrpc": "2.0", "id": 14, "result": { "success": true, "added_count": 1 } } Deprecated methods on editor.landscape
The following methods still work on editor.landscape but include a "deprecated" field in the response pointing callers at the new editor.foliage equivalents:
| Old method | New method |
|---|---|
editor.landscape.getFoliageTypes | editor.foliage.getTypes |
editor.landscape.getFoliageInstances | editor.foliage.getInstances |
editor.landscape.removeFoliageInstances | editor.foliage.removeInstances |
Related
- API Reference index
- editor.vegetation -- Procedural Vegetation Editor (PVE / Megaplants) on UE 5.7+
- editor.landscape -- landscape heightmap, layers, materials
- editor.pcg -- procedural content generation, adjacent surface for AI-driven placement