C++ editor mode plugin in Unreal Engine 4

C++ editor mode plugin in Unreal Engine 4

This blog post will be about settings up an editor mode plugin in UE4. Settings up this plugin was part of my third years’ specializations (2 times 8 weeks to research a game related subject) where I specialized in the creation of a voxel terrain editor plugin for the Unreal Engine. I did this to learn more about Unreal’s internals and C++.

Because of UE4 being open-source, the subsystems are fully extensible. This allows you to add your own functionality to the engine by using and modifying the existing functionality without altering the engine’s source code. You can add your own menus, menu items, windows or subsystems to the editor or engine. For this specialization I created an editor mode plugin that allows you to create and manage voxel terrains (Figure 1) and is located in the modes tab in the editor. If you want to see how the terrain is created, check this blogpost.

Figure 1: Editor modes in UE4

Figure 1: Editor modes in UE4

 

The plugin

Creating an editor mode plugin is very easy, just open the plugins window in the edit menu (Figure 2) of the editor. If click on “new plugin” you can select a variety of template plugins. In this menu we select “Editor mode“. The editor mode template provides you with some basic C++ code for a user-interface with some simple functionality. After regenerating your visual studio project, you can open your project’s code. The newly created plugin is now located in the project’s plugins folder. The base for my code is retrieved from the landscape editor, I advise you to use it as reference since this part of the engine is not well documented.

1

Figure 2: Plugins window

 

If you check the .uplugin file in your plugin’s root folder you will see that it will have one defined module. Modules are packages of code that build up your plugin which will be compiled separately. The default module is set to type “Developer“, this means that the module will only be compiled to development builds and will not work with standalone builds. Because the module with the editor mode contains editor specific code, the module won’t compile to standalone builds. If you want to add Actors for instance which need to be available during runtime builds, you have to set up a second module in your .uplugin file and set its type to “Runtime“. After adding a module to your plugin you have to create a new source folder for that module in your plugin’s source folder.

Slate framework

Slate is Unreal’s low profile, completely customizable and platform independent user interface framework. The framework is designed to create user interfaces for tools and applications such as the unreal editor or in-game user interfaces. The slate framework combines a declarative syntax with readability in mind. This framework’s goal is to make UI designing more easy and fun.

You can add widgets to your plugin’s user-interface to your editor mode by going into the toolkit .cpp file. The “SAssignNew” functions defines your editor mode’s UI and you can add custom widgets to it with the “SNew” function in which you defined that kind of widget you want to add (Button, texture, label etc.). The engines core provides you with a good amount of tools that help you create these slate interfaces with the most important one to us being the details panel builder (Figure 3). This widget takes a “UClass” with “UProperties” and will turn it into an editable user interface. You can create a details panel like this:

Now to turn the details panel into a widget, use it’s shared (DetailsPanel.ToSharedRef()) and add it to your user interface as if it where an SNew function.

Figure 3: Details panel widget

To enable and disable properties conditionally you can add custom metadata to your UProperties like I did in Figure 4. To enable and disable using the metadata, you have to create a custom function that checks whether a property should be visible or not and register that function to the property editor module like so:

In the function you can get the property, check if it contains the metadata and return a boolean that states whether to property should be visible or not.

props

Figure 4: UProperties with custom metadata

Customizing the details panel

To customize your details panel and add buttons and labels to it like in Figure 3, you can register a custom class layout to your property editor module. The custom class layout is a class that extends the IDetailCustomization interface which will force you to implement the CustomizeDetails function. In this function you can add new rows of widgets to your details panel. You can register your customize class like this:

In this function the name used is the name of your ‘to be customized’ class. The MakeInstance function is just a static function that will return a sharedref of a newly created instance of the customize class.

 

Plugin style set

To add graphics to your plugin and change the icon that represents your editor mode in the modes tab, you need to define a “SlateStyleSet“. The style set contains the sprites, brushes and fonts for the plugin. I added a custom class to my plugin that is responsible for the graphics, containing the style set and loading its resources. Creating a style set is quite simple, you can create a style set like this:

You can add assets to your style set using the style set’s Set function. After you’ve registered your style set, all assets can be used throughout your application using the style set’s name and the icon’s name. The assets added can be used on custom slate widgets such as buttons and images. In order to change the module’s icon, open the plugin’s core class’s .cpp file. In the line where the plugin is registered you can add a new “FSlateIcon“. To its constructor you pass the names of the style set and the icon you want to use.

Adding content

Finally, if you want to add content to your plugin, you should add ‘”CanContainContent”: true‘ to your .uplugin file. After re-opening the editor, you can view your plugin’s content directory in the content browser by enabling “Show plugins content” in the content browser’s view options. Now you can add materials, textures or actors to your plugin.

15 Comments

  1. Phyronnaz

    Hi Rune!

    I’m currently developing a plugin similar to yours (https://github.com/Phyronnaz/MarchingCubes), and I’d like to have an in-editor editing.
    However browsing the UE source is quite time consuming, and you seem to have already developed such a feature for your plugin.

    As you said you were not working on your plugin anymore, I was wondering if you could release its source?
    It would be of a great help, and you would of course be added to the contributors of the project.

    Thanks!

    Phyronnaz

    1. Rune de Groot

      Hi Phyronnaz!

      Great job on the plugin and props to you for making it an open source project! You are right about the tooling beeing part of this project though I must confess that I am not very satisfied with the current implementation.
      I would be very interested in making this project open source to share my knowledge. Thanks for this suggestion! Perhaps you could contribute to the tooling issue after I release the source.

      Keep an eye on my blog where I’ll post an update about the project going open source. I will look into this ASAP.

      Rune

  2. Gergely G.

    Hi! Sorry for my question, but what object type is the DetailsPanel? The engine’s documentation is pretty unusable for this part, and I’m trying to make an EditorMode plugin, but I’m stuck with details panels… I was programming in C# before, so I know in C# I can define custom variable with var keyword, but in C++ it doesn’t work. With the ToSharedRef() method will it turn to a Slate widget? I can’t really find good documentation for this part, because I don’t want to customize the details panel. Thanks: Gergely

    1. Gergely G.

      Hi! I was able to figure things out, and my project builds fine with the details panel, but the Editor crashes when I try to open my plugin… I did everything as written. The error is Access Violation, in the line where I use SAssignNew.

    2. Gergely G.

      Hi! Sorry for the lot of comments, but now my only problem is that the DetailsPanel->SetObject(((FMyClass*)GetEditorMode())->UISettings); generates Access violation error.

    3. Rune de Groot

      Hi Gergely, my guess is that you haven’t made an instance of the UISettings’s class. You can assign a new instance of the class in the editor mode’s constructor like this:

      UISettings = NewObject< [YOURUCLASS]>(GetTransientPackage(), TEXT(“[YOURUCLASS]”), RF_Transactional);

      Is this enough to help you out? The UClass is a class that extends UClass with UProperties in it.

      Rune

    4. Gergely

      Really big thanks for your help! This was the problem, and you wrote the answer just about ten minutes later than I found that line in the landscape editor code… :) Your tutorial is a life-saver. Would it be a problem if I’d make a post about this thing on Epic’s wiki? I’d link this tutorial as the base, and I can’t understand why they didn’t make any docs for these parts of extending the editor… Your plugin looks pretty awesome!(I just tried the demo, and an editor mode like that… That would make unreal even more unreal… :) ) Will you release it?(Or have I missed it?)
      Thanks again for your help: Gergely

    5. Rune de Groot

      Hi Gergely,
      No problem! You can post this on the wiki if you like if you make a reference to this post.
      About the plugin, it has been a nice experiment as part of my education but I’m currently not planning on further development of the tool.
      Rune

  3. Benoit

    I’m carefully looking to that too. Many people are waiting for a good free or opensource alternative to Voxel Farm or the future Landscape Architect, to grow and dig their voxel landscape. If you consider to release your source code with open-source licence, I wouldn’t be suprised to see some people joigning you in the developpement.

    Good luck with your graduation and we hope to hear from you soon.

  4. christoph

    Hey, Rune!

    I stumbled upon your blog when looking for UE4 Voxel systems.

    Will your plugin and voxel tools ever be available on the marketplace or maybe even open source? I found other voxel systems that are open source (basically, they just require credits) but they lack in-editor tools. I haven’t really dealt with editor plugins so far, so I don’t know if I could maybe do them myself, but lazy as I am, I googled it first ;)

    Your posts are really interesting, though it still lacks means of accessing your work :D I understood that you are busy with your graduation, but please consider making your code and plugin accessible. Indie devs might not want to or even be able to afford a 200-300$ license for Cubiquity or VoxelFarm. A cheaper alternative or maybe just some good tutorials would be great for people like me who only do this as a hobby and don’t even know if they’re ever gonna release a game!

    Thanks for sharing that great stuff and keep up the good work!

    Chris

    1. Rune de Groot

      Hi Cristoph!

      That’s right, I’m currently busy graduating and sadly haven’t got time to develop on this project. There’s one major reason why I’m not releasing the plugin as for now, I’m not really satisfied yet with the smoothness of the tools. Fixing this issue involves some math and programming that requires time which I currently do not have :(

      If I can solve this issue I will release the tool and I’m even thinking to make it open source so everyone can help adding new features to the plugin!

      As for now, I would like to refer to my set of blog posts that broadly explain some interesting aspects of this plugin. If you have basic C++ knowledge, creating an editor plugin with UI really isn’t that difficult. If you create a new plugin trough the plugins window, Unreal already provides you with some basic sample code which should get you going. This is also briefly explained in this blog post.

      Thanks for the kinds words!

      Rune

    2. christoph

      I’m happy to hear that!

      I wish you success with your graduation and I’m really looking forward to hearing from you again!

      Thanks and cheers!

    1. Rune de Groot

      Hi suhaib,

      You can SAssign a new SButton in your toolkit .cpp class in the SAssignNew function. This would look something like this:

      SAssignNew(ToolkitWidget, SScrollBox)
      +SScrollBoxSlot()
      [
      SNew(SButton)
      .Text(LOCTEXT(“Create”, “Create”))
      .OnClicked_Raw(this, &FVoxelTerrainEdModeDetails::OnCreateButtonClicked)
      ];

      Here the OnCreateButtonClicked function is passed as a sort of event that is triggered once the button is clicked.

      Good luck!

    2. suhaib

      i know about SAssignNew() but i need to add button as property in the public header .h file like
      UPROPERTY(EditAnywhere)
      FText DevloperToken;

Leave a Reply

Your email address will not be published. Required fields are marked *