Fix Landscape Deformation at Distance in UEFN with Python

UEFN does not currently expose the Max LOD Level property in the Landscape Details panel.

This can cause detailed Landscape shapes to become heavily simplified or deformed at a distance. However, the hidden max_lod_level property can be changed through UEFN Python editor scripting.

The video below shows a synchronized comparison using the same Landscape, camera path, and graphics settings.

  • Before: max_lod_level = -1
  • After: max_lod_level = 0

-1 is the default automatic LOD behavior.
0 restricts the Landscape to LOD 0 at all distances.

Python script

Select one or more Landscape actors in the Outliner, then run this script:

import unreal


# ============================================================
# Force LOD 0 only on the selected Landscape actors.
#
# max_lod_level:
#   -1 = Default automatic LOD behavior
#    0 = Force LOD 0 at all distances
#    1 = Allow up to LOD 1
# ============================================================

MAX_LOD_LEVEL = 0


def is_landscape_actor(actor):
    if actor is None:
        return False

    class_name = actor.get_class().get_name()

    return class_name in {
        "Landscape",
        "LandscapeProxy",
        "LandscapeStreamingProxy",
    }


def describe_actor(actor):
    return (
        f"{actor.get_actor_label()} "
        f"({actor.get_class().get_name()})"
    )


actor_subsystem = unreal.get_editor_subsystem(
    unreal.EditorActorSubsystem
)

selected_actors = list(
    actor_subsystem.get_selected_level_actors()
)

if not selected_actors:
    raise RuntimeError(
        "No actors are selected.\n"
        "Select one or more Landscape actors in the Outliner, "
        "then run the script again."
    )


invalid_actors = [
    actor
    for actor in selected_actors
    if not is_landscape_actor(actor)
]

if invalid_actors:
    invalid_actor_list = "\n".join(
        f"  - {describe_actor(actor)}"
        for actor in invalid_actors
    )

    raise RuntimeError(
        "The selection contains non-Landscape actors.\n"
        "The operation was cancelled to prevent accidental changes.\n\n"
        f"{invalid_actor_list}"
    )


with unreal.ScopedEditorTransaction(
    "Set Selected Landscape Maximum LOD Level"
):
    for actor in selected_actors:
        actor.modify()

        old_value = actor.get_editor_property(
            "max_lod_level"
        )

        actor.set_editor_property(
            "max_lod_level",
            MAX_LOD_LEVEL,
        )

        actual_value = actor.get_editor_property(
            "max_lod_level"
        )

        unreal.log(
            "[SelectedLandscapeLOD] Success: "
            f"{describe_actor(actor)}: "
            f"max_lod_level {old_value} -> {actual_value}"
        )


unreal.log(
    "[SelectedLandscapeLOD] Completed. "
    "Press Ctrl+S to save or Ctrl+Z to undo."
)

To restore the default automatic LOD behavior, change:

MAX_LOD_LEVEL = -1

Notes

Forcing LOD 0 may increase rendering cost, particularly on large Landscapes. Performance should be tested on all target platforms.

I also tested the following hidden Landscape properties:

  • lod0_screen_size
  • lod0_distribution_setting
  • lod_distribution_setting
  • lod_blend_range

These properties produced IllegalPropertyOverride validation errors in my project, so they are intentionally not included in the script above.

In my test, max_lod_level did not appear in that validation error list.