Dear Epic and Community,
I’ve made a new editor feature pull request to Epic adds two functions to the engine to:
-
Take all selected static mesh actors with same static mesh asset, and convert them into an instanced static mesh (ctrl + i)
-
Reverse the procedure in 1, taking into account whether the original instanced static mesh actor was a Blueprint class.(ctrl + shift + i)
You can view this pull request and add your support here!
https://github.com/EpicGames/UnrealEngine/pull/917
**Result: Easy-To-Use Instanced Static Mesh Actor Editor**
The result is that for a minimal amount of additional code in the Engine, you can now easily edit Instanced Static Mesh Actors in **world space**!
You edit the Instanced Static Mesh as regular static mesh actors, and then merge them together when you are done!
You can go back and edit any particular instance at any time by reverting the instanced static mesh!
Goal Accomplished
I wanted to make it easy for UE4 users to get the performance advantages of Instanced Static Mesh actors while maintaining the convenience of the familiar level editor viewport duplication,rotation,scaling, and translation tools!
I have accomplished this Goal!
**Videos**
**Video 1**
This first video is the plugin version, where I demo the core usefulness.
My fps goes from 9 back to 120 once I convert all the static mesh actors into an instanced static mesh.
I then demonstrate going back in and editing a single instance and then restoring the whole structure to being an instanced static mesh actor again.
*Massive performance gains!*
https://youtube.com/watch?v=iC1sjgalEJg
Video 2 ~ Editor Integration
**Video 3 ~ Blueprint Support!**
https://youtube.com/watch?v=2PPPYl2MC6o
UE4 Editor Undo/Redo
Undo and Redo are fully supported for both creating and reverting the instanced static mesh actor!
I demonstrate this in the second video which is of the Editor-Integration version (this pull request)!
const FScopedTransaction Transaction(LOCTEXT("CreateInstancedStaticMeshFromSelection", "Create Instanced Static Mesh Actor From Selected Actors"));
//...
//ISM fully created
NewISM->Modify();
**Versatile Code**
When creating an instanced static mesh actor from a group of selected actors, all the other static meshes that are selected use the static mesh and materials of the "root selected static mesh actor."
But this does not have to be the very first actor in the selection set!
In fact in one of my videos, I accidentally highlight a Directional Light along with all my static mesh actors, and my code still runs just fine!
This is because I simply choose the first found static mesh actor in the selection set as the root.
```
//Root Selected Static Mesh Actor's Component
UStaticMeshComponent* RootSMC = nullptr;
for (FSelectionIterator It(*GEditor->GetSelectedActors()); It; ++It)
{
AStaticMeshActor* EachSMA = Cast<AStaticMeshActor>( *It );
if(!EachSMA)
{
//Not an SMA
continue;
}
//Has root SMC been found yet? (Component of first of selection that is an SMA)
if(!RootSMC)
{
RootSMC = EachSMA->GetStaticMeshComponent();
//Search tags to see if an ISM class was specified
for(const FName & Each : EachSMA->Tags )
{
```
Supports Any Number of Materials on Mesh
Please note I am careful to copy all materials during the creation/reverting of the Instanced Static Mesh Actor!
//Materials
const int32 MatTotal = EachISM->GetMesh()->GetNumMaterials();
for(int32 v = 0; v < MatTotal; v++)
{
Mesh->SetMaterial(v,EachISM->GetMesh()->GetMaterial(v));
}
**BP Support**
My system fully accounts for whether or not the user made a BP out of my new base class, Instanced Static Mesh Actor, and will use that BP class instead!
I do this by adding a tag to the static mesh actors that are created from the BP instanced static mesh actor (when reverting to individual editable meshes).
This tag is serialized of course!
So the user can come back any time and if they take their separate meshes that came from a BP Instanced Static Mesh Actor, they simply press the key to re-create the ISM that comes from their own BP!
This means users can create all manner of Blueprint code for use with the Instanced Static Mesh Editor system that I am presenting to you!
```
//Did the root static mesh actor have an ISM class tag?
TSubclassOf<AInstancedStaticMeshActor> ISMClass =
(TagClass && TagClass->IsChildOf(AInstancedStaticMeshActor::StaticClass())) ? TagClass : AInstancedStaticMeshActor::StaticClass() ;
AInstancedStaticMeshActor* NewISM = GetWorld()->SpawnActor<AInstancedStaticMeshActor>(
ISMClass,
RootSMC->GetComponentLocation() , RootSMC->GetComponentRotation(), SpawnInfo
);
```
Simple Hotkey Key Presses
I simply added two editor hotkeys, CTRL + i and CTRL + SHIFT + i to run the two commands!
void FLevelEditorActionCallbacks::OnCreateInstancedStaticMeshFromSelection()
{
if(GCurrentLevelEditingViewportClient)
{
GCurrentLevelEditingViewportClient->CreateInstancedStaticMeshFromSelection();
}
}
void FLevelEditorActionCallbacks::OnRevertInstancedStaticMesh()
{
if(GCurrentLevelEditingViewportClient)
{
GCurrentLevelEditingViewportClient->RevertSelectedInstancedStaticMeshes();
}
}
**InstancedStaticMeshActor**
Again please note the addition of InstancedStaticMeshActor to the code base, not reflected in the git code changes summary.
```
/**
* An Instanced Static Mesh Actor renders all instances in a single draw call making it much more efficient
* than the equivalent number of individual static mesh actors
*
* The only restriction is that all instances share the same materials and static mesh asset.
*
* @see https://docs.unrealengine.com/latest/INT/Engine/Actors/InstancedStaticMeshActor/
* @see UInstancedStaticMeshComponent
*/
UCLASS(hidecategories=(Input), showcategories=("Input|MouseInput", "Input|TouchInput"), ConversionRoot, ComponentWrapperClass, meta=(ChildCanTick))
class ENGINE_API AInstancedStaticMeshActor : public AActor
{
GENERATED_UCLASS_BODY()
private_subobject:
UPROPERTY(Category = InstancedStaticMeshActor, VisibleAnywhere, BlueprintReadOnly, meta = (ExposeFunctionCategories = "Mesh,Rendering,Physics,Components|StaticMesh,Components|InstancedStaticMesh", AllowPrivateAccess = "true"))
UInstancedStaticMeshComponent* Mesh;
public:
/** Returns InstancedStaticMeshComponent subobject **/
class UInstancedStaticMeshComponent* GetMesh() const;
};
```
Conclusion
So there you have it!
With only a minimal amount of code I am enabling everyone to edit Instanced Static Mesh actors in world space using all the familiar tools used during normal level editing!
And also supporting Blueprint-based custom Instanced Static Mesh Actor classes!
My gift to you, the Community and Epic!
Enjoy!
[FONT=Comic Sans MS]
Rama
PS: If you like this pull request please support it on Github itself!
https://github.com/EpicGames/UnrealEngine/pull/917