@Nate, Thanks! If we get a reproduction case, I’ll let you know.
@Nate, congratulations on getting Prefab Tool in the Marketplace - I just pick up a copy myself :).
Any updates on converting prefab to actor blueprint?
It’s still in planning stage (been distracted from migrating to 4.17 release), I will start the implementation next week.
Good to hear! Thanks!
@Nate, We have a reproduction case for the Rename crash. The problem seems to revolve around sub-levels.
Make sure bUpdateAllPrefabActorsWhenOpenMap = true
- Create a new map/level. Call it MapA
- In this level drop an actor and name it TestName.
- Make this actor into a prefab.
- Save MapA.
- Create a new map/level. Call it MapB.
- Drop a new actor and ALSO name it TestName.
- Make this actor into a prefab.
- Save MapB.
At this point, you have two maps each with a prefab that has an actor with the same name as the other. This example has two different prefabs, but if you use the same prefab in each map, I believe you’ll get the same result.
- Create a new map/level. Call it WorldMap.
- In the Levels window, add in MapA and MapB.
- Exit and restart (so map load happens and bUpdateAllPrefabActorsWhenOpenMap happens).
I hope this lets you find the problem!
I dug around a bit in the code and I think I may have found the problem. I’m not very knowledgeable about this stuff in Unreal , so I might be off base.
The intent of RevertPrefabActor is to replace an existing prefab actor’s hierarchy with the one defined in the asset. To do this, it collects a bunch of information about the particular instance and then calls SpawnPrefabInstances to get a new hierarchy to replace the old one. Eventually, ReplacePrefabInstances is called to rename the new actors to their original names. Although the rename code here looks good, somehow a name conflict happens and it crashes.
Although the rename code in ReplacePrefabInstances looks clean, it still dies when using multiple sublevels. When debugging, I noticed that the new actors weren’t in the expected level. They were in the base map, not the sub level.
So, I went to look at how they were spawned. SpawnPrefabInstances calls edactPastSelected, which pastes the new actors into the World’s current level. So, I decided to set the World’s current level before calling SpawnPrefabInstances. Here is my hack/fix:
at approximately PrefabToolHelpers.cpp:1804
// Spawn prefab instances TArray<AActor*> SpawnInstances; TArray<AGroupActor*> NewGroupActors; PrefabActor->GetLevel()->OwningWorld->SetCurrentLevel(PrefabActor->GetLevel()); SpawnPrefabInstances(Prefab, PrefabActor->GetLevel()->OwningWorld, SpawnInstances, &NewGroupActors); PostSpawnPrefabInstances(Prefab, SpawnInstances, PrefabActor, &NewGroupActors);
This seems to keep the crash from happening. Previously, the new objects were all going into the base map but I think MakeUniqueObjectName makes a unique name in the outer of the old actor. But the place we’re pasting into isn’t in that context. So we can step on our own toes. This poited out that those actors might not have been created in the right level anyway. So, by fixing the level they are spawned in, it fixes the problem.
At least that’s the theory. Let me know if there’s a more appropriate fix or if I’m just off-base.
@ColdIronPoz, thanks a lot for the reproduction case and the bug hunting! You’re absolutely right about the root cause of the bug: the wrong assumption of current level of world is the same as the prefab actor’s outter level.
I’m preparing a hot-fix release now.
220.127.116.11 update live on itch.io. Unreal marketplace update submitted.
18.104.22.168 Change Log
Thanks for the fix! We’ve deployed it and is seems to be working well.
One unrelated thing: The prefab plugin doesn’t compile properly in non-unity builds. Mostly it’s missing some headers in cpp files. But a harder fix is that PrefabComponentDetails.cpp calls FPrefabAssetEditorModule::ShowHidePrefabActor. But that class and function is only defined in PrefabAssetEditorModule.cpp. I think the class will need to be hoisted up to a header for it to compile.
(We’re preparing our code for IWYU, so we’re doing some non-unity builds to make sure we’re doing the proper includes.)
@ColdIronPoz, thanks for letting me know the compile issue in non-unity build, I’ll push a update for that.
Any news about Prefab-to-BP actor (and back) conversion ?
Working on that, hopefully I can wrap it up this weekend. (The first implementation will only support prefab -> BP actor conversion though)
I am thinking of this kind of scenario: make Prefab > convert it into BP actor > edit and update Prefab > BP actor automatically gets updated. Is it something that you plan on having in the first iteration of the feature ?
Now that we’ve been working with this a little bit, we’ve run across some workflow speed-bumps and thought you might have some ideas about how to overcome them. Or maybe take them as suggestions for future updates.
It’s not obvious when you select an actor that it is part of a prefab. I’ve moved stuff around, saved, and when I re-opened the map the changes are lost because the Prefab is still connected. I can imagine a few ways to approach this workflow problem. One would be to have the actors in the prefab be Grouped using Unreal’s editor groups and have that Group be locked as long as the Prefab is connected. When you try to choose an actor that’s inside that prefab, you’d know immediately that you were doing so. To move things inside the prefab, you’d have to disconnect it. (I assume this behavior would need to be an option for people with other workflows.)
In our workflow, most prefabs should be disconnected because we always tweak the items in it a bit. But by default, dropping in a prefab leaves it connected. There are also times where we do want it connected. It turns out that some prefabs are meant to be used one way and others the other way. So, maybe we could mark a Prefab asset as “is disconnected by default.” (Internally, we call these kinds of prefabs “Stamps”, because you stamp them into the map.) (Or maybe they shouldn’t even be connected any more; I’m not sure about that.)
One more requests since I’m here: Select all siblings/children - If you have a prefab selected, select all the children. If you have a prefab child selected, select all the siblings.
Thanks again for this tool. It is really great.
1.0.4 update now live on itch.io. Marketplace update submitted.
Thanks a lot for the suggestions.
I like the “stamp” prefab and the select sibling/children ideas, will find a way to implement them in future updates.
For the grouping prefab actors, I actually have once implemented that functionality in early prototype, but remove it since I found grouping not works well when nested. I’ll re-visit the grouping idea, and maybe add it as an experimental feature.
The new blueprint generation feature added in 1.0.4 is basically do what you described, except the changes on Prefab have to be apply to blueprint explicitly.
The blueprint generation support need to be enabled in editor preference first.
Then you can:
1. Generate Blueprint to make a blueprint from selected prefab.
2. Update Blueprint: to update blueprint with selected prefab
**3. **the Update Blueprint operation is using the “Generated Blueprint” field as the update target, you can change the “Generated Blueprint” to make vary versions of blueprints base on same prefab actor.
1.0.5 update is now live on itch.io. Marketplace version submitted.
This update is mainly for resolving lightmap data lost issue when re-opening map.
1.0.5 - Add option to check if prefab content changed before updating all preab actors when opening map
I just bought the plugin on the Marketplace. Is this version live yet? I’m using 4.15.3 still, not sure if it’s still getting updates.
@Sitrec, thanks a lot for your support.
Sorry that the marketplace version is still on 1.0.3.
I’ve submitted 22.214.171.124 update on 08-15, 1.0.4 update on 08-24, and 1.0.5 update on 09-14, but none of them been published yet. I’m still trying to contact unreal marketplace support for status update.