I have a data file type, and a C++ library to read/write this data file type.
The file type describes a procedural layout of objects – a little like a lightweight scene, except much more specialized.
I want these files to be included in cooked game data as uassets.
I’d like to create an actor type that can be configured with one of these assets, and inflates it into geometry, both in editor, and in game.
My guess is that an appropriate way to go about this is:
Derive my actor type from instanced-static-mesh-actor
Define a new asset type that I can “import” from my data type, and which generates .uasset files.
Inside the construct script, and each time the configured asset changes, my actor will remove any previously-created static mesh instances, and then re-create new instances based on the loaded data.
What I’m looking for is a map or description about how to go about #2.
How do I create a new asset type that I can “import” in the content browser, and that I can generate references to as properties for my new actor?
What are all the bits I need to implement to make:
file import dialog select right file type
content browser type filter recognize this asset type
actor property asset picker (like “texture picker” or “mesh picker”)
thumbnails for imported assets
actually creating the .uasset file from the selected raw import data
What are the base classes, how do they fit together, and how are they called/managed by the engine?
As you can see with FactoryCreateText, you can return any UObject as asset.
So as long as your asset class is a UObject with serializable UProperties it should just magically work.
This should take of everything except the thumbnail - I have no idea how that works, maybe have a look at the content browser code.
For the thumbnails, he have to create a new Slate Style class and tell Style to register the thumbnail brush as his class icon to be used in the Editor.
Up to 4.12 you have to call FIconFinder::RegisterIconSource(…) and grab the icon from your new Style class; on 4.13 and above, Editor will do this automatically for you; example:
#define PLUGIN_BRUSH(RelativePath,...) FSlateImageBrush(FMyStyle::InContent(RelativePath,TEXT(".png")),__VA_ARGS__)
class FMyStyle {
private:
static TSharedPtr<FSlateStyleSet> StyleSet;
static FString InContent(const FString &RelativePath, const TCHAR* Extension);
public:
static void Initialize();
}
void FMyStyle::Initialize() {
if (StyleSet.IsValid()) {return;}
//
const FVector2D Icon16x16(16.0f,16.0f);
const FVector2D Icon128x128(128.0f,128.0f);
//
StyleSet = MakeShareable(new FSlateStyleSet(TEXT("FMyStyle")));
StyleSet->SetContentRoot(IPluginManager::Get().FindPlugin(TEXT("MyPluginName"))->GetContentDir());
//
StyleSet->Set("ClassIcon.MyObjectClass", new PLUGIN_BRUSH(TEXT("Icons/Fsm_16x"),Icon16x16)); // Registers icon for my "UMyObjectClass"
StyleSet->Set("ClassThumbnail.MyObjectClass", new PLUGIN_BRUSH(TEXT("Icons/Fsm_128x"),Icon128x128)); // Note how it ignores class prefixes. Don't use here 'A', 'E', 'F', 'U', etc;
//
FSlateStyleRegistry::RegisterSlateStyle(*StyleSet.Get());
//FClassIconFinder::RegisterIconSource(StyleSet.Get()); /// Depricated 4.13! Call this if you are on 4.12 or bellow...
};
After you do that, simply call Initialize() somewhere; usually inside a plugin’s startup function: