Instancing interface to TScriptInterface property

I have two properties:

UPROPERTY()
	TScriptInterface<ICoordinateSystem> CoordinateSystem;

UPROPERTY(EditAnywhere)
	TSubclassOf<UCoordinateSystem> CoordinateSystemType;

How can I instantiate CoordinateSystemType to CoordinateSystem?
I have tried different ways like

CoordinateSystem = NewObject<ICoordinateSystem>((UObject *) GetTransientPackage(), *CoordinateSystemType);

CoordinateSystem = NewObject<UCoordinateSystem>((UObject *) GetTransientPackage(), *CoordinateSystemType);

CoordinateSystem = Cast<ICoordinateSystem>(NewObject<UCoordinateSystem>((UObject *) GetTransientPackage(), *CoordinateSystemType));

but none of them compiles saying something like it can’t convert UObject* to ICoordinateSystem* or ICoordinateSystem* to UObject* in either NewObject or TScriptInterface = operator.

Not sure if you are still looking for an answer to this, but since Ive just struggled through it might as well have an answer here for you or anyone else

I assume you you have some existing pointer to an object type that implements ICoordinateSystem

Try this:

MyTypeThatImplements* myPtr = blah;

if (myPtr->GetClass()->ImplementsInterface(UCoordinateSystem::StaticClass()))
{
    CoordinateSystem.SetInterface(Cast<ICoordinatSystem>(myPtr));
    CoordinateSystem.SetObject(myPtr);
}

This will correctly instantiate your TScriptInterface property

You can then call ICoordinateSystem interface methods as

if (CoordinateSystem != nullptr)
{
    CoordinateSystem->Execute_MyInterfaceMethod(myPtr);
}

HTH

Actually no, I want to create an instance of type in CoordinateSystemType and store it to CoordinateSystem.

First up, UCoordinateSystem is a wrapper class for the ICoordinateSystem … I do not think you should be using it as a reference type (if you followed the interface implementation for UE4 approach)

So you have a class or set of classes that implements ICoordinateSystem?

All of those classes extend UObject.

Your CoordinateSystemType class should restrict to the lowest base class that will include the set of all coordinate system types (e.g.)

TSubclassOf<UObject> CoordinateSystemType;

You can then create an instance of your coordinate system type

CoordinateSystemType = NewObject<UObject>(this, MyTypeThatImplements::StaticClass());

And then assign it to the CoordinateSystem interface pointer as detailed above.

You cant just create an instance of an interface you have to create an instance of a class that implements that interface then you can cast that object to your interface type.

You cant just create an instance of an interface you have to create an instance of a class that implements that interface then you can cast that object to your interface type.

That is obvious :confused: Your solution is same as simply making type property type UClass. With such approach you get none of possible benefits like limitations for editor UI. So you will be able to set its value to some class which doesn’t implement interface at all.
Also TSubclassOf is type to store classes, not objects. So you can’t store UObject objects there, but you can store any type extending UObject so it’s same as simple UClass variable.
Anyway I am not trying to instantiate interface, I am trying to instantiate a type, passed from editor, limited to types implementing interface.

The problem you have is that I dont think there is an easy way to get a list of all types that implement an interface directly or inherit the interface from a base class. I do not think you can use the UCoordinateSystem wrapper type in this manner to filter your type list, but im no expert, and its not really clear what youre trying to do from your question.

The TSubclassOf member variable you have must use a type that is lowest common denominator of classes that implement ICoordinateSystem, I just gave UObject as an example, if there is no common base class then you will be stuck with UObject.

If you are able to obtain the type that is appropriate then you need to create an instance of it using NewObject and then do as I have indicated to populate the TScriptInterface.

You cant assign an object instance cast to your interface type straight to the TScriptInterface as it has an Interface component and an object component. You have to set both otherwise you get the UObject* error you mention.

You can have only the class that implement your interface by adding something like this:

UPROPERTY(EditDefaultsOnly, meta = (MustImplement = "CoordinateSystem"))
TArray<UClass*> CoordinateSystemType;

Satan bless you, good man, first sane comment! Anyway, looks like an answer. ^^

IAimable* aimable = …
TScriptInterface ayyyy;
ayyyy.SetInterface(aimable);
ayyyy.SetObject(reinterpret_cast<UObject*>(aimable)); //UInterface instances are always UObjects so this is safe
dude->startAim(ayyyy); //you then free to use that TScriptInterface object as you please

I have tested it and it works although the value of this variable/attribute is not kept in the instance, every time you reload the level it is reset to none.