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.
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:
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.
Levels in unreal aren’t assets, they’re objects. I couldn’t find anything that would return objects from a given directory.
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.
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)