Python, create streaming level

Hi all experts,
I am trying to create levels on datasmith import and then loading them into a main level. It looks like there is a way to create streaming levels from within the loaded level, but I don’t understand how to enter the *level_streaming_class *in *classmethod *create_new_streaming_level(level_streaming_class, new_level_path="", move_selected_actors_into_new_level=False).

when I try to make an object of class unreal.LevelStreamingAlwaysLoaded I get the error:


Cmd: py "D:/p4/LayersToLevels/Rey_Import_DS.py"
LogPython: Error: Traceback (most recent call last):
LogPython: Error:   File "D:/p4/LayersToLevels/Rey_Import_DS.py", line 31, in <module>
LogPython: Error:     streamingClass = unreal.LevelStreamingAlwaysLoaded()
LogPython: Error: TypeError: LevelStreamingAlwaysLoaded: Outer '/Engine/Transient' was of type 'Package' but must be of type 'World

I tried giving it the result of levelLibrary.get_editor_world() but that gave the same error.

thanks for looking at this problem.

Hello Damien,
Same problem here.
Do you find any solution to handle level streaming with python?

I’m trying to do the exact same thing. What the heck does create_new_streaming_level() expect for that first parameter?

It really is self explanatory at the API:

create_new_streaming_level(level_streaming_class, new_level_path="", move_selected_actors_into_new_level=False)

the first param, is :
https://docs.unrealengine.com/en-US/…LevelStreaming

So to make it more clear, there are multiple types of “level streaming”, such as those:

2020-05-27 20_28_52-Search — Unreal Python 4.25 (Experimental) documentation.png

So with a simple script like this:

I can create a dynamic level streaming at the selected location, which will result the file right away:

2020-05-27 20_28_28-MyProject - Unreal Editor.png

And a success “green” python log as well

So, just pick the type of the desired level. And be sure to NEVER set it to the unreal.LevelStreaming, as this is considered as “parent” class, which will freeze or crash the editor.

I did add this example to the public free unreal python scripts github repository:

Hope this was clear :slight_smile:

Which was EXACTLY what I was doing and wondering why the hell it wasn’t working. Thank you for the detail and example. It is VERY much appreciated.

Do you know if it’s possible to add an existing level instead of creating a new one?
I’m tired of manually add in the “Levels” window my levels.

addexisting.jpg

Any ideas if it’s possible to add an existing level like Lexingtoon asked? Or is that just not possible?

Hey folks,

I was up against the problem of automatically adding existing levels, too, and I came up with a method. It’s probably not the most elegant method, but it does work. A note, though. There’s a function called unreal.EditorLevelUtils.add_level_to_world that only seems to work in 4.26. This whole thing is going to seem a little weird, but here are the problems I was working around that necessitated the strange approach.

  1. Levels in unreal aren’t assets, they’re objects. I couldn’t find anything that would return objects from a given directory.
  2. I could use os to get all the files in a directory, but getting the full path to the project required jumping through a few hoops.
  3. I always ended up with a \ in my file path. I couldn’t replace it with string.replace, so I had to split the string with , then join it back together with a /. Weird and a pain, but it works.

Ok, without further ado, here’s the script.

import unreal

import os

@unreal.uclass()
class levelUtil(unreal.EditorLevelUtils):
    pass

# This is the level that is currently open in the editor. This is where your levels will be added.
world = unreal.EditorLevelLibrary.get_editor_world()
# This boils down the currently open level to just the name. I use this later to make sure I don't try to add a streaming level into itself
worldSplit = str(world).split("/")
worldSplit2 = worldSplit[len(worldSplit) - 1].split(".")
worldTrack = worldSplit2[0]

# This is the directory where your project is stored.
projPath = unreal.Paths.convert_relative_path_to_full(unreal.Paths.get_project_file_path())

# I need the actual file path of the project, and since the "Game" folder is actually called "Content", this replaces "Game with "Content".
temp = projPath.rfind("/")
newPath = projPath[0:temp]
newPath += "/Content/"

# This is an array that will hold my levels.
maps = []

# This goes through the project directory and returns every file therein.
for root, directories, files, in os.walk(newPath, topdown=False):
    for name in files:
        # This is a file.
        asset = os.path.join(root, name)
        # In the end, I just need the relative path to the level, so this bit boils it down to just that.
        firstSplit = asset.split("/")
        checker = False
        mapPath = ""
        for bit in firstSplit:
            if checker:
                mapPath += "/" + bit
            elif bit == "Content":
                mapPath = "/Game"
        # This splits the file name at the "." and checks if it's a "umap" file type. If it is, it goes into the maps array.
        secondSplit = firstSplit[len(firstSplit) - 1].split(".")
        if secondSplit[len(secondSplit) - 1] == "umap":
            if secondSplit[0].find(worldTrack) == -1:
                maps.append(mapPath + "/" + secondSplit[0])

for map in maps:
    # I had a heck of a time replacing the \ with a /, but this seems to work.
    mapSplit = map.split("\\")
    newMap = mapSplit[0] + "/" + mapSplit[1]
    # This adds the streaming level to your currently open level.
    levelUtil().add_level_to_world(world, newMap, unreal.LevelStreamingAlwaysLoaded)

addLevels.py (2.2 KB)

Hello, anyone knows how to remove a level in the current scene instead? I’m new here so I hope it’s ok to ask on this post, thanks in advance