Sorry if this seems like a simple question, but how exactly would one create an object that is visible to the content browser (editor) through c++?
This mainly pertains to inbuilt objects such as materials, curves etc.
So I guess the question is, how do I create a UCurveFloat / UCurve object using C++ that will appear in the content browser? – (Seems I’ve tried everything! )
Assets are just UObjects, but you need to do a few things to register them as Assets. Someone has made an Text Asset Plugin which I used to see how I can make my own Assets. Everything you need to know is included there, how to register it and how to make your own editor for it.
If you want to learn more about it, you need to dig through the Unreal code and see how they have done it.
I have had an extensive dig around in the source for how it is implemented, however I’m 100% sure on how to call a factory to create an object.
As far as I can tell, creating an object is a matter of a line such as the following:
NewObject(InParent, InClass, InName, Flags) – Which occurs within the factory.
Being that factories are the preferred method of creating objects, how does one call a factory to create an object? – I believe I am on the right track, but I am getting unresolved externals
Edit: Sorry if I sound frustrated, I’ve just been at this for a couple of days, digging around trying to find something that should by all accounts be easy. I’ve even tried backtracking from the GUI options when you right-click on the content browser to create an object.
First, have you looked in the “TextAssetEditor.Build.cs”? You need to add a few dependencies to your module to use the AssetTools
PrivateIncludePathModuleNames.AddRange(
new string[] {
"AssetTools",
...
Then you also need to implement an asset action for your asset and register it in your module, the action tells the editor what name your asset has and to what category it belongs. You can leave out the “GetActions” function and return false at the “HasActions” function.
Take a look at the “TextAssetEditorModule.cpp” and at the “TextAssetActions” files. If you leave out the “OpenAssetEditor” function, unreal will just open a default property editor window for your asset.
When you have registeres your asset action, the asset shows up in the category you specified and the “FactoryCreateNew” function is called when you add the asset. You probably have to restart the editor, I think the hot reload don’t work fine with this.
So I understand how to go ahead and configure a NEW type of asset that can be added to the Content Browser, so when I right-click to add a new asset it will iterate through all the factories (as seen in NewAssetOrClassContextMenu.cpp) and the new asset will be one of the options.
However, if I want to add that Asset automatically using CODE as part of my plugin (or even a custom blueprint module etc), how do I do this?
How do I call the UFactory interface specifically to create the asset? – Is it something like the following?
Okay, I missunderstood your question first, thinking you just wanted to creat it by context menu, sorry for that :), but your question is quite complicated but got me interested as I want to also know how to do that now.
But I digged a little bit in the code and may found what you are looking for. In the “LevelEditorViewport.cpp” file in the “GetOrCreateMaterialFromTexture(…)”(Line 395) function is a good example how to do that. It seems the “InParent” must be a UPackage, and you need to create it with a proper file name but I think you can figure out how to make that name. The “CreatePackage(…)” function is global.
The rest of the parameters a very simple:
InClass is simple, just use “YourAsset”::StaticClass() to get the class.
InName is obvious and you can copy the flags from the example.
Context can just be a nullptr and for Warn they just use the globel GWarn variable.
However I am getting unresolved symbols, I wonder if this is because the definitions for UCurveFactory or UCurveFloatFactory do not have ENGINE_API flagged on them?
EDIT:
Same result with the following as well…
auto CurveFactory = NewObject<UCurveFloatFactory >();