Editor plugin workflow

Hi,
I’m trying unreal for my project I’m developing now in unity to find how it goes. As first I want to describe how I’ve setup my project in unity, my workflow there and then how it is done in unreal. I’ve tried to search the forums but haven’t found some detail post about the implementation. Also I want to note that I’m C++ developer (as my day job) and using C# only in unity.

Now, in unity I have my custom .DLLs where I have code for the whole game (classes, struct, MonoBehavior derived classes, some helper classes for the unity editor plugins). All the code I use is in one of the many .DLLs. The raw .cs files (as in the “Asset” folder) I’m only using for the testing. The only instance when I’m using the .cs files are for my editor extension/plugins.
Here is one example. I have editor plugin (which is “ran” from some menu item) where I create custom terrain (It creates GameObject which had some mesh component, some custom MonoBehavior derived class, TerrainComponent, which holds some data describing the terrain (which are serialized), and some methods which could be called on this particular terrain). The process of the terrain creation is like this: I read some prepared file, parse it, create the main game object (GO) for the terrain. To this GO I attach my MonoBehavor derived component (which has some other plain C# class instances as fields), TerrainComponent, from my .DLL. Then I create the mesh, save it as the assets and add the mesh component to the GO which will used the newly created asset as mesh. Then I do some other stuff and add some other components but I would rather not discuss it for the simplicity). Then when the scene is saved then the terrain GO is saved as usual with TerrainComponent fields etc.

Now for the unreal. Whats the workflow there? As first, could I have some custom .DLL which will use the unreal SDK and then use it in unreal project? That is, in unity I can create the c# assembly with some custom classes etc. and then use it without any hassle in the unity. I do think that this could not be as straightforward in unreal. From what I’ve read the one solution is to maybe make some runtime plugins and then used those. But what about dependencies? If I recall correctly, the plugins should not have any dependencies on the another plugins. So have can I then make some editor plugin, which would encapsulate the logic of the terrain creation as described above, using some other plugins classes? Maybe I’m misunderstanding something, I don’t know:) So what’s the recommended work flow for my situation?

Thank you,

Trigve

Anyone?

I’ve come across to some post about plugins (https://answers.unrealengine.com/questions/83155/cannot-find-dll-when-using-an-uobject-exported-via.html). So it looks like, the game plugin could be dependent on the game code, but not the other way around. I’m I right?
I was also thinking about the serialization. So if I create some custom Actor through the editor plugin in the scene and the actor has some fields (could be or not UPROPERTY), how is the serialization done? Is there some method for serializing the fields that aren’t exposed as UPROPERTY?

Thanks

I’m not very familiar with the Unity workflow, so I’m not sure I quite understand your problem. Both your game and plugin code can be split into multiple modules, which you specify in your .uproject or .uplugin file under the “Modules” list. Each module can be set to be load in the editor-only (“Type”: “Editor”), or in both the game and editor (“Type”: “Runtime”).

The page at https://docs.unrealengine.com/latest/INT/Programming/Plugins/index.html has some more information on it, but it might be more useful to check out the PlatformerGame sample, which uses a FootIK plugin to position the character’s feet (and has a separate runtime and editor module).

It’s certainly not desirable to have a dependency from a plugin module onto a game module, because that would prevent the ability to drop it into another project (which is the whole point of making a plugin). Do you actually need to be able to separate out the plugin functionality from your game, or do you just need to move it into a different module?

Ben

Thank you very much for the reply, Ben.

I have already looked at the plugin documentation and has tried to do some simple editor plugin. It is compiling and working fine (albeit doing nothing as no functionality is done there). I’ve tried to find the Platformer sources but couldn’t find it (in the marketplace it said “coming soon…”).

Maybe I have misunderstood modules, but I was thinking that modules are something like libraries that are divided in some logical parts of which unreal is aware (something like static/dynamic libraries in the normal world). Am I right? Or do they have some higher level functionality?

Regarding the plugins/modules, I was thinking that I would need to have editor plugin to extend editor and run some code from there in the edit mode.

What I want to do, is something as simple as this: I want to have some custom menu/button in the editor (through editor plugin?) which when activated, some code is run which creates my procedural terrain (that is, my custom actor ATerrainActor (which would have mesh component, collider component, some private fields, etc) is spawned in the scene - that is some file is parsed, mesh is created and saved as assets, some data are from the file is “saved” as some private fields of the class) which could be then used in the game. So I want to generate my custom terrain in the edit mode.

This is how it could be done, maybe (?): Create some game module, where I create ATerrainActor + some other classes that are used by ATerrainActor. Create editor game plugin, which will use this new game module (ATerrainActor class). In the editor code I spawn the actor (create new instance, etc, etc - Can I pass some arguments to the constructor? How?). The actor is placed in scene a all should be ok.

And regarding the the fields in the ATerrainActor class which aren’t exposed as properties: How are they handled? That is if I have some private field and set it some value in the constructor. This value isn’t persisted, as for instance UPROPERTY, is it? That is, when I start the game in the editor, the value of this field should be undefined (or value initialized?), am I right?

Thank You

Yes, you’re correct about modules. You don’t need to use plugins to extend the editor though.

The terminology is perhaps a little surprising, but plugins are just groups of modules that you can distribute and enable/disable as one discrete thing. From a user’s point of view, you can install or enable a plugin to get some high level behavior, but any extensibility features in the engine are actually implemented at the module level. To extend the editor for your game, you don’t need to create a plugin - you just need to create an editor module that’s part of your game.

This post might point you to the API for adding custom buttons: https://answers.unrealengine.com/questions/25609/customizing-the-editors-toolbar-buttons-menu-via-c.html.

There are a bunch of different ways that the editor might need to construct your object; serializing from disk, because it’s replicated over the network, or because the user has pressed “undo” after deleting an object, for example. To handle all those cases, it’s normal to just have a default constructor which initializes everything to some sensible values, then setup the object in whichever way you need from another function. I believe you can derive a UFactory class which will allow you to use the editor’s standard object creation UI, though it’s not an area I’m very familiar with.

Only UPROPERTY tagged fields are serialized, so everything else will be initialized to the value you assign to it in your constructor. We zero out the memory that’s allocated for objects before the default C++ constructors are run, so POD C++ types will be initialized to zero.

Does that help?

Thank you for the reply,
That’s good I don’t need to use the plugins. Also thanks for the link, I’ll study it later and try to experiment with the editor.

So it looks like you’re serializing the objects in the same manner as the unity does it. Then the question is, could I somehow serialize some custom class instances that aren’t UObject-derived (that is non-intrusively)? For instance std::map<>? In unity there interface ISerializationCallback which if one implements, some special method is called before serialization and some other after the deserialization. I was thinking if UObject does some overrides for the serialization? I’ve found some PreXXX() methods, particularly UObject::PreSave() which could be used for saving the data and UObject::PostLoad() for deserialization. Could I use them for custom data serialization?

I’m not very familiar with the editor, right now, so I don’t necessary know what you mean by “… editor’s standard object creation UI”. Anyway I was hoping to use the Slate for creating some simple dialog when extending the editor. Hope this is possible.

Sure, your post helped me a lot :slight_smile: I wish there would be more documentation about high-level things like extending the editor and not-so-often-used stuff. You know the way how the things are working, what need to be done in some high-level steps for certain functionality etc.

Thank you

edit: Because you can’t have custom parameters in constructor, then “const” fields that need explicit initialization cannot be used in the class, can they?

Yes, you should be able to just use Slate to create your own UI for initializing an object. I don’t know of anything technically stopping you from using const fields, but you probably can’t get to anything useful to initialize them from. You can add the “Const” modifier to stop it being modifiable in the editor, if that’s useful to you: https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/Reference/Properties/index.html.

Custom serialization for a UObject is implemented by overriding the Serialize() method. There are quite a few classes in the engine that do custom serialization for their data, so if you search for that you’ll find lots of examples.

Ben

Once more, thanks a lot for the answers :slight_smile: