Download

Difference between DataAssets (e.g. Material) and ClassAssets (e.g. Blueprint)

When creating a variable in a Blueprint and setting the Type to Material, you can set the default value of the variable to a material from the ContentBrowser.

Settings the variable type to another Blueprint, you can’t set the default value, as an instance of a blueprint is required.

A material is only a class as is the blueprint, but the material basically only has a single instance and thus can be referenced in the variable default.

I’m trying to reference a BlackmagicTimecodeProvider asset in the variable defaults, but it behaves like a Blueprint, not like a material and thus I can’t get the reference.

A BlackmagicMediaOutput behaves like a material and thus causes no issue for me.

I looked at the classes in C++ but can’t make out anything that defines the class as “Data” (single instance) or as “Class” (multi instance).

Every class created in C++ per default seems to behave as “Class”.
What do I need to do to create “Data”?

Managed to do it.

You need a Factory:

UCLASS(hidecategories = Object)
class HYBRIDMIDDLEWARE_API UTimecodeProviderBlackMagicFactoryNew
: public UFactory
{
GENERATED_BODY()
public:
/**

  • Creates and initializes a new instance.
    */
    UTimecodeProviderBlackMagicFactoryNew(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
    {
    SupportedClass = UBlackmagicTimecodeProviderFixed::StaticClass();
    bCreateNew = true;
    bEditAfterNew = false;
    }

//~ UFactory Interface

virtual UObject* FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override
{
return NewObject(InParent, InClass, InName, Flags);
}
};

A action class:

class HYBRIDMIDDLEWARE_API FTimecodeProviderBlackMagicActions
: public FAssetTypeActions_Base
{
public:

/**

  • Creates and initializes a new instance.
    */
    FTimecodeProviderBlackMagicActions()
    {}
    public:

//~ FAssetTypeActions_Base overrides

virtual uint32 GetCategories() override
{
return EAssetTypeCategories::Media;
}
virtual FText GetName() const override
{
return NSLOCTEXT(“AssetTypeActions”, “AssetTypeActions_BlackmagicTimecodeProvider”, “Blackmagic Timecode Provider”);
}
virtual UClass* GetSupportedClass() const override
{
return UBlackmagicTimecodeProviderFixed::StaticClass();
}
virtual FColor GetTypeColor() const override
{
return FColor::White;
}
};

And register the actions:

class FHybridMiddlewareModule :
public IModuleInterface
{
public:
//~ IModuleInterface interface
virtual void StartupModule() override
{
RegisterAssetTools();
}

virtual void ShutdownModule() override
{
UnregisterAssetTools();
}

virtual bool SupportsDynamicReloading() override
{
return true;
}

protected:
void RegisterAssetTools()
{
IAssetTools& AssetTools = FModuleManager::LoadModuleChecked(“AssetTools”).Get();
RegisterAssetTypeAction(AssetTools, MakeShareable(new FTimecodeProviderBlackMagicActions()));
}

void RegisterAssetTypeAction(IAssetTools& AssetTools, TSharedRef Action)
{
AssetTools.RegisterAssetTypeActions(Action);
RegisteredAssetTypeActions.Add(Action);
}

void UnregisterAssetTools()
{
FAssetToolsModule* AssetToolsModule = FModuleManager::GetModulePtr(“AssetTools”);

  if (AssetToolsModule != nullptr)
  {
  	IAssetTools& AssetTools = AssetToolsModule->Get();

  	for (auto Action : RegisteredAssetTypeActions)
  	{
  		AssetTools.UnregisterAssetTypeActions(Action);
  	}
  }

}

private:
TArray<TSharedRef> RegisteredAssetTypeActions;
};

This helped to figure it out: Adding New Asset Types to UE4 | gmpreussner

Note: When you declare your own class as UCLASS(Blueprintable), you can still inherit from it in Blueprint. Though, inheriting will create a “Class”. Only the Asset created via the Actions and the Factory will be “Data”

Note2: It did not help with the TimecodeProvider, as the “Data” can’t be set in the settings…

I made the mistake of making a whole new custom asset type instead of just using DataAssets once. If you create a subclass of UDataAsset, it will create a custom data asset that can be created through Add->Miscellanious->Data Asset. All of the properties will be exposed, editable, and saved like a normal asset.

In this case it was not an option to use UDataAsset as I need to inherit from UBlackmagicTimecodeProvider.

Good, just making sure!