Hello. I wanted to create a level using data I have on rotations and locations of some actors. Sort of like importing a terrain heightmap.
For example I have 1000 wall pieces that will each use a random texture (from a set of textures) and I have already generated the placement using an algorithm outside of UE4 (I have data containing rotations and locations of each piece). I don’t want to manually drag each actor into the level, assign it the texture and transform.
How would I do this programmatically?
I want the level to be built once and have it stay the same for every player who ever uses it so it doesn’t need to be procedural or change ever again.
Basically, GEditor->GetEditorWorldContext().World()->SpawnActor… (op in the question used AddActor, but spawn works just fine).
Followed by actor setup (static mesh component, etc), followed by
Thanks! That makes wonderful sense. Now I need to learn how to do that lol
Any great tutorials come to mind? I found a few already but none seem to be great and if you know any off that top of your head that would be awesome. If not thanks for pointing me in the right direction!
You don’t really need a plugin for that if you don’t want to make one.
You can do it through one actor’s construction blueprint graph. Every time you create/place an actor or change any of it’s params, the construction graph is executed.
Your external data, you can import as CSV data, just need to create an importer struct in C++ for it then you can use anyway you’d need them.
So you are saying in an actor I can cause it to create items that would permanently exist in the level? There is no spawn actor function available in the construction blueprint. Am I missing something?
I tried for a while and can easily make it spawn on begin play and do everything I want but then of course when the level ends none of the objects still exist in it. I also did it in the construction script by calling a function which spawns the actor but I couldn’t get it working. Can you clarify?
I’m guessing spawn is the wrong path to follow because that would only create objects when the game is running.
He was talking about spawning objects while the game is running.
Actor spawned from within editor plugin will stay on the map, well, unless you forget to save the map. It is the same thing as adding them manually.
Actor spawned while the game is running will disappear when you reload the level.
However, you could store list of actors to spawn in external file/resource and implement their persistence this way.
Potential issues:
Last time I checked, you can’t bake lightmaps into objects you spawn at runtime. No such problem when spawning stuff from editor plugin.
Also, when spawning large number of objects into editor (5000 of them) I encountered minor issue where you’ll encounter significant fps drop (down to single digit framerates) right after spawning objects, and fps loss will stay until you press “build” button (meaning it is instantly fixable). After that fps goes back to sane level (60…70). I’d guess you’ll get the same issue if you start spawning lots of objects at runtime, except that there won’t be a “build” button to press.
I’ve tried many variations of GEditor Getworld and GetEditorWorldContext and SpawnActor and Actors.Add and AddActor. I have tried loading the level and adding objects to it. I stopped receiving errors at a certain point and now am just trying random things but nothing appears! I have tried adding it as AActor and as UClass. Loading it with and without the _C and many combinations.
If I do this I get nothing in the logs but nothing happens.
With this it triggers a breakpoint:
UClass* LevelPieceObj = LoadObject<UClass>(nullptr, TEXT(“Blueprint’/Game/Levels/SurfaceChunk.SurfaceChunk_C’”));
GEditor->GetEditorWorldContext().World()->SpawnActor<UClass>(LevelPieceObj, FTransform(FVector(0)));
In Casts.cpp and tells me
“Cast of
FromType 0x0000000011e6f000 L"SurfaceChunk_C /Game/Levels/Level1.Level1:PersistentLevel.SurfaceChunk_C_0”
to
ToType 0x0000000021a1bac0 L"Class"
failed"
I’ve tried many variations but I either get cast failures, it cannot find the object, or nothing happens at all (no logs, nothing).
I haven’t found any other examples of this that work for me and would love some help if anyone sees what is going wrong!
I’m still using the constructor with child actors. The time it takes doesn’t seem to scale linearly and I capped it at 400 per actor (started at 2000 and ended up killing the editor process). I think this is because it is difficult to control when the constructor fires so you may end up creating and destroying thousands or tens of thousands of actors for each 100 you are creating.
I only need one or two per level though as I will stream them so I imported the data in one giant chunk with an indexing column I use in each actor that says if == yourNumber then make this child actor. Then I drag each spawning actor into its relevant level. It all works well for the moment but feels a bit hacky. Since implementing the C++ plugin method should yield identical results I can go ahead with other design stuff until I figure the C++ method.
No idea. I’m actually doing paper2d stuff. It’s still somewhat frustrating and I would love to be able to figure out the C++ method but this at least lets me continue working.
Because the first thing I tried when I installed ue4 was attempt to build level with modular blueprints. Lightmaps did not bake for blueprinted actors and were marked brown in lightmap density view. ( Viewport Modes in Unreal Engine | Unreal Engine 5.3 Documentation )
There you can set the creation script as a Blueprint and call it with a button. For example, in my case I’m spawning N bluprinted actors at random positions.
You can also make another button to destroy them.
Might still not be the same as handspawning them because when deleted the editor complains they are still referenced by my spawning actor, but it’s pretty neat.